Как работает дизеринг
Мне хотелось сделать минималистичный анимированный фон для личного сайта — что-то живое, но ненавязчивое. Я знал про шум и дизеринг, но не понимал, как он устроен. Чтобы разобраться, я попросил Claude собрать интеракстивную страницу, чтобы пошагово в нем разобраться. Результатом решил поделиться здесь, поэтому давайте разбираться вместе.
Март • 2025
Экран умеет светить только яркими точками — но мы видим на нём оттенки серого. В картридже только чёрные чернила — но принтер печатает фотографии. Game Boy показывал 4 цвета — но художники создавали иллюзию десятков.
Всё это — дизеринг. Трюк, который заставляет глаза видеть цвета, которых на самом деле нет.
Что такое картинка на самом деле
Картинки выглядят гладкими и непрерывными. Но если увеличить достаточно сильно — вы увидите, что они состоят из крошечных цветных квадратиков — пикселей.
Наведи курсор, чтобы увидеть значение яркости
Каждый пиксель хранит три числа: сколько красного (R), зелёного (G) и синего (B) подмешать. Каждое число от 0 (нет) до 255 (максимум). Попробуй смешать сам:
Чтобы работать с дизерингом, нам достаточно одного значения яркости. Для этого переводим пиксель в оттенок серого по формуле, которая учитывает чувствительность глаза к разным цветам: 0.299R + 0.587G + 0.114B.
А что, если мы хотим оставить только два цвета — чёрный и белый? Как сделать так, чтобы картинка всё ещё выглядела узнаваемо?
Обман зрения из двух цветов
Вот ключевая идея: если поставить рядом много чёрных и белых точек в правильной пропорции, глаз смешает их и увидит серый. Больше чёрных точек — темнее. Больше белых — светлее. Попробуй сам:
Этот трюк и есть дизеринг. Газеты, старые компьютеры и GIF-картинки используют его каждый день. Возьмите лупу и посмотрите на фото в газете — оно состоит из крошечных точек. А художник Жорж Сёра рисовал целые картины из тысяч цветных точек — вблизи хаос, издалека красота.
Простой подход: просто обрезать
Самый простой способ превратить картинку в чёрно-белую — пороговая обрезка (квантование). Берём каждый пиксель и сравниваем с порогом (обычно 128): светлее — белый, темнее — чёрный.
Просто, но грубо. Попробуй с разными значениями яркости:
Пиксель с яркостью 96 станет чёрным (0), хотя он был тёмно-серым. Разница между оригиналом и результатом — это ошибка квантования. Если применить такую обрезку ко всей картинке — плавные градиенты превращаются в уродливые полосы. Это называется бандинг.
Градиент (оригинал):
После квантования (2 уровня):
Пиксель со значением 128 → 255. Ошибка: 127
Умный подход: не выбрасывай ошибку
Вместо того чтобы просто терять ошибку, алгоритм Флойда–Стейнберга (1976) делает неочевидную вещь: передаёт ошибку соседним пикселям, которые ещё не обработаны.
Аналогия: ты учитель и раздаёшь конфеты. Каждый ученик получает строго 0 или 10 штук. Первому полагается 7 — даёшь 10 (лишних 3). Эти 3 «лишние» вычитаешь у следующих учеников. В итоге в среднем по классу — справедливо!
Алгоритм работает в три шага:
Шаг 1: квантуй пиксель. Берём текущий пиксель и округляем его яркость до ближайшего доступного уровня. При двух уровнях (чёрный/белый): если яркость ≥ 128 → белый, иначе → чёрный.
Шаг 2: вычисли ошибку. Ошибка = исходная яркость минус новая. Это то, что мы «потеряли» при округлении. Например: пиксель 96 стал чёрным 0. Ошибка: 96 - 0 = +96. Мы потеряли 96 единиц яркости!
Шаг 3: передай ошибку соседям. Флойд и Стейнберг придумали точные веса для четырёх соседей. Порядок обработки важен — мы идём слева направо, сверху вниз. Поэтому ошибку получают только пиксели справа и снизу.
× — текущий пиксель. Числа — доля ошибки, которая распределяется на соседей.
Смотри, как ошибка распределяется шаг за шагом:
Pixel * has brightness 96.
It's less than 128, so it becomes black (0).
Error: 96 - 0 = +96
These +96 units of brightness need to go somewhere!
Каждый соседний пиксель «наследует» часть ошибки и учитывает её при своём квантовании. Так средняя яркость области сохраняется, и глаз видит правильный тон.
Почему именно 7, 3, 5, 1? Потому что 7 + 3 + 5 + 1 = 16, и деление на 16 — это сдвиг битов, что очень быстро для компьютера. А ещё эти веса создают идеальный шахматный паттерн для 50% серого.
Смотри, как это работает
Теперь давай увидим весь алгоритм в действии на маленькой сетке. Числа внутри пикселей — их текущая яркость (с учётом полученных ошибок от предыдущих). Синяя рамка — текущий пиксель, оранжевые — те, кому передаётся ошибка. Нажимай и наблюдай:
Входные значения (+ ошибка):
Результат:
Шаг 1/36: пиксель [0, 0]
Значение: 0 → чёрный (0). Ошибка: 0
Полный конвейер
Дизеринг — это конвейер из четырёх шагов, каждый из которых трансформирует картинку:
- Оригинал — полноцветная RGB-картинка
- Оттенки серого — переводим каждый пиксель в одно число яркости
- Квантование — округляем до N уровней. Появляются полосы
- Дизеринг — то же квантование, но с передачей ошибки. Полосы исчезают
Если навести курсор на любой этап — видно пиксели вблизи. Можно загрузить своё фото.
Оригинал
Оттенки серого
Квантование
Floyd-Steinberg
Почему это важно
Идея «не выбрасывай ошибку, а передай её дальше» оказалась на удивление универсальной. Флойд и Стейнберг опубликовали её в 1976 году, и она до сих пор работает повсюду.
Печать. Газеты, журналы, лазерные принтеры — все используют дизеринг для передачи оттенков одним цветом чернил.
GIF-формат. Максимум 256 цветов. Дизеринг сохраняет плавность переходов в анимациях.
Ретро-игры. Game Boy, NES, ранние Mac — художники создавали шедевры пиксель-арта с помощью дизеринга.
Экраны. E-ink дисплеи (Kindle) используют дизеринг для показа фотографий на чёрно-белых экранах.
Звук. Аудио-дизеринг добавляет микроскопический шум при конвертации из 24 бит в 16 бит, чтобы замаскировать искажения квантования. Без него тихие звуки звучат «грязно».
Нейросети. Квантование весов нейросетей — та же идея: меньше бит, но с компенсацией ошибки.
В итоге дизеринг я обновил фон сайта. Но для меня главным оказалось другое: интерактивный инструмент — лучший способ разобраться в алгоритме и его логике.