Бандинг, шиммер и прочие привидения шейдинга
Вы отрендерили сцену, и вдруг: на склоне лестница из цветовых полос, на хромированном бампере мурашки, а дорожная разметка мигает при каждом шаге камеры. Это не баг художников. Это привидения шейдинга — и у каждого свой скелет в шкафу.
Бандинг: ступени вместо градиента
Плавный переход света превращается в видимые полосы. Причина: на 8-битный канал не хватает оттенков, и между «темно» и «светло» физически нет промежуточных значений. Классика — закатное небо и мягкие тени на больших плоскостях.
Лекарства: - Dithering — добавление мелкого шума перед квантованием. Полосы рассыпаются в зерно, которое глаз не читает как границы. В Unreal это встроенная опция, в самописных шейдерах — пара строк с хешем координат пикселя. - HDR-рендер и 10/16-битные буферы кадра. Если считаете освещение в float, а режете в 8 бит только в самом конце, полос будет резко меньше. - Не экономьте на форматах текстур окружения: 8-битная cubemap для отражений — гарантированный бандинг на металле.
Шиммер на нормалях
Металл «кипит» при движении камеры. Виновник — normal map в 8-bit RGB. Нормаль хранится как вектор, и на плавных изогнутых поверхностях квантование 256 значений на ось даёт ступени, которые при взгляде под углом превращаются в рябь.
Лечится просто: нормальные карты — в сжатых форматах с двумя каналами и высокой точностью (BC5/ATI2, ASTC соответствующего блока). Один канал вычисляется из второго, точность направления вырастает вдвое. Бонус: файл меньше.
Z-fighting: два объекта воюют за один пиксель
Полигональные швы мигают, декали то всплывают, то тонут. Это конфликт глубины: две поверхности почти совпали, а z-буфер не различает их — не хватает разрядности.
Порядок действий: 1. Разводите поверхности физически: декаль на 1–2 см над стеной, а не в ноль. 2. Сдвигайте polygon offset по настроению, но помня: он лечит симптом, а не причину. 3. Расширяйте дальнюю плоскость отсечения. 8-битная или даже 16-битная глубина на дистанции 10 км — это микронные шаги на близкой дистанции. Дальняя плоскость 1000 метров вместо 10000 часто решает всё. 4. Современный ответ — reversed depth buffer: максимум точности там, где камера реально бывает.
Шиммер на дальних планах и текстурах
Разметка мерцает вдали — не хватает mip-уровня или анизотропная фильтрация выключена. Мир дрожит при движении — floating point precision: координаты объектов в 10 км от начала координат теряют разряды. Лечится world origin rebasing: мир «переезжает» к игроку, а игрок стоит в нуле.
Диагностика
Прежде чем лечить, определите привидение: замрите камеру. Мерцание пропало — это проблема точности/фильтрации, зависящая от ракурса. Осталось — квантование (бандинг, нормали) или z-конфликт. Дальше бейте точечно: dithering, BC5, offset, дальняя плоскость. Привидения редкостно уходят от «повысить качество всего» — но почти всегда уходят от понимания, где именно кончились разряды.
Комментарии (1)
Z-fighting на декалях лечил смещением наугад года три. Оказалось, есть depth bias и нормальные решения.
Форма для гостей комментариев пока не принимается — писать можно автору (expeot@outlook.com) или через владельца блога. Все записи выше настоящие, никто их не модерирует молча.