For the view field

ordinary line-wise dithering with horizontal error transfer
int main() { const int S = 300; // Размер поля const int R = 256; // Диапазон яркостей for (int y = 0; y < S; ++y) { int error = 0; for (int x = 0; x < S; ++x) { int ideal = (x + y) * (R - 1) / (2 * (S - 1)); int corrected = ideal + error; int bw = corrected < R / 2 ? 0 : R - 1; error = corrected - bw; // Исходное поле: нарисовать точку (x, y) с яркостью `ideal` // Дизеринг: нарисовать точку (x, y) с яркостью `bw` } } }
gives the following picture

(the pattern will depend on the size of the image). And if you need something more tricky - you decide.
Purely for fun:
The same, line by line, but with changing directions "back and forth" and with the global spread of the error

Simple unidirectional dithering along the diagonals from the lower left to the upper right.

Dithering around concentric squares, from the lower left corner counterclockwise, with global error propagation

The same, but with a random choice of the starting point on the square

Your initial version, however, was not obtained by such methods, but by a more cunning distribution of the error in neighboring points.