Компьютерная графика
Тени и глобальное освещение
В 2007 году Crysis предложил включить SSAO - и большинство игроков его тут же отключили: видеокарты не справлялись. Сегодня тот же эффект выполняется за 0.5ms на телефоне. Тени и глобальное освещение - это история компромисса между физикой и производительностью.
- **Unreal Engine 5 Lumen** - динамический один отскок GI в реальном времени, стандарт ААА-игр 2023+
- **Fortnite / RDR2** - CSM для теней солнца: 4 каскада, плавные переходы на все дистанции
- **Архитектурная визуализация** - path tracing в Blender/V-Ray: часы рендера ради фотореализма
- **Мобильные игры** - light probes + SSAO, запечённые заранее: GI без затрат в реальном времени
История техник освещения
Shadow Maps предложил Лэнс Уильямс в 1978 году - алгоритм практически не изменился за 45 лет. SSAO появился в Crysis (Crytek, 2007) и буквально за год стал стандартом индустрии. Rendering Equation сформулировал Джеймс Кейджия в 1986, но первые real-time GI решения появились только с Unreal Engine 4 Lumen Preview в 2020.
Shadow Maps: тени через глубину
Фотография делается с одной точки зрения. Если поставить камеру в позицию источника света и сделать снимок глубины - получится карта того, что свет «видит». Всё, что дальше этой глубины в финальном кадре, находится в тени.
**Shadow Map** - это двухпроходный алгоритм. Первый проход: рендер сцены с точки зрения источника света, записываем только z-значения во float-текстуру (depth texture). Второй проход: для каждого фрагмента трансформируем его в пространство источника света, сравниваем его глубину с depth texture.
Без **depth bias** возникает «shadow acne»: фрагмент сравнивается сам с собой с погрешностью float и считает себя в тени. Небольшой сдвиг bias (0.005) устраняет это. Но слишком большой bias - и тень «отрывается» от объекта (Peter Panning).
Тени из одной shadow map выглядят ступенчатыми: текстура 1024×1024 проецируется на большую сцену, каждый тексель растягивается. **PCF (Percentage Closer Filtering)** решает это - вместо одного сравнения делается 9 или 16 сравнений в окрестности, результаты усредняются. Тень становится мягкой.
**Алиасинг shadow map:** 1 тексель карты тени покрывает большую площадь на сцене. Решения: увеличить разрешение карты, использовать PCF, или Cascaded Shadow Maps.
Что такое «shadow acne»?
Cascaded Shadow Maps: тени для открытых миров
Одна shadow map 4096×4096 покрывает либо детали вблизи, либо большой радиус вдали - одновременно не бывает. Вблизи нужна плотность текселей, вдали достаточно грубого приближения. **Cascaded Shadow Maps (CSM)** делят frustum камеры на зоны и дают каждой свою shadow map.
На границе двух каскадов может быть видна резкая смена качества. **Cascade blending**: в переходной зоне шириной ~10% рендерятся оба каскада, результаты интерполируются по расстоянию. Граница становится незаметной.
CSM применяется в каждой современной AAA-игре для солнечных теней: Unreal Engine 4/5, Unity, CryEngine. Разрезка frustum - log-linear: ближние каскады тонкие (там важна детализация), дальние - толстые.
**Практика:** UE5 по умолчанию использует 4 каскада для солнца с разбивкой ~10m / 50m / 200m / 1000m. В мобильных играх часто 2 каскада ради производительности.
Зачем в CSM ближние каскады тонкие, а дальние - широкие?
SSAO: затемнение щелей в экранном пространстве
Пыль скапливается в углах. Свет не проникает в щели между предметами. Это не тени от конкретного источника - это общее затемнение закрытых участков. **Ambient Occlusion** имитирует, насколько «доступна» точка для рассеянного света.
**SSAO (Screen Space Ambient Occlusion)** - алгоритм Crytek, впервые показанный в Crysis (2007). Работает полностью в screen space: для каждого пикселя берётся полусфера случайных точек вокруг него, проверяется по depth buffer, сколько из них «заглублены» относительно поверхности.
Результат SSAO зашумлён - 64 случайных образца дают гранулярность. **Blur pass** (обычно bilateral blur - размывает, сохраняя края) сглаживает шум. После blur SSAO выглядит как реальная окклюзия.
Ключевое ограничение: screen space. Если геометрия, создающая окклюзию, вне экрана - SSAO её не видит. Подоконник за краем экрана не отбросит тень на стену. **HBAO+ (NVIDIA)** и **GTAO** улучшают качество, но ограничение экранного пространства остаётся принципиальным.
**Crysis 2007:** игроки массово отключали SSAO, потому что GeForce 8800 не справлялась. Сейчас SSAO выполняется за 0.3-0.5ms на мобильном GPU - за 15 лет разрыв в 50-100x.
SSAO не затемняет угол между стеной и потолком, хотя они геометрически близки. Наиболее вероятная причина:
Global Illumination: один отскок меняет всё
Красная стена в солнечной комнате окрашивает пол в розоватый оттенок - свет отражается от стены и попадает на пол. Это **indirect light** - свет, сделавший хотя бы один отскок. Без него сцена выглядит пластиково: тёмные стороны объектов абсолютно чёрные.
Физически корректная модель - **Rendering Equation** (Kajiya, 1986). Она говорит: исходящий свет из точки = собственное излучение + интеграл по всем входящим направлениям (прямой + отражённый). Точный расчёт интеграла требует трассировки бесконечных лучей - нереально в реальном времени.
- **Path Tracing:** эталон качества, слишком медленный для real-time. Используется в рендерах (Blender Cycles, V-Ray), кинематографе. One sample per pixel + denoising (DLSS Ray Reconstruction) - граница возможного в 2024.
- **Light Probes:** заранее запечённые сферические гармоники в ключевых точках сцены. Каждый объект интерполирует irradiance из ближайших probes. Быстро, но статично - не реагирует на динамические изменения освещения.
- **Lumen (UE5):** гибрид signed distance fields + screen space + hardware ray tracing. Один отскок indirect light в реальном времени. ~2-5ms на 1440p, динамически реагирует на смену времени суток.
**Цветокровение (color bleeding):** красная стена рядом с белым кубом окрашивает куб в розовый. Это классический тест GI. Без GI куб будет чисто белым. С light probes - слабый намёк. С path tracing - фотореалистично.
Ambient цвет (константа 0.1) - это аппроксимация глобального освещения
Константный ambient - это заглушка, не аппроксимация. Он не зависит от геометрии, нормалей или цвета соседних поверхностей.
Настоящий GI - это пространственно-переменный indirect light. Константный ambient одинаков в открытом поле и в закрытом ящике, что физически неверно.
Light Probes не подходят для динамических сцен (день-ночь цикл). Причина:
Тени и глобальное освещение
- Shadow Map: рендер с позиции света → depth texture → сравнение глубин с bias
- PCF: усреднение нескольких сравнений → мягкие тени без артефактов
- CSM: 3-4 shadow map на разные зоны frustum → детали вблизи + охват вдали
- SSAO: случайные образцы в полусфере → ambient occlusion; ограничение: только screen space
- GI: один отскок indirect light меняет восприятие сцены; path tracing - эталон, light probes - mobile
- Lumen (UE5): динамический GI за 2-5ms через SDF + ray tracing
Связанные темы
Тени и GI - надстройка над базовой моделью освещения и depth buffer.
- Модель освещения: Phong и PBR — GI дополняет прямое освещение indirect компонентой
- Z-buffer и глубина — Shadow map - это depth buffer с точки зрения источника света
- Текстуры и сэмплирование — Shadow map читается как текстура; PCF - билинейная фильтрация глубин
Вопросы для размышления
- Почему depth bias в shadow maps - это всегда компромисс, и нет универсального значения?
- В каком сценарии light probes предпочтительнее Lumen, несмотря на худшее качество?
- Как screen-space ограничение SSAO влияет на дизайн уровней в AAA-играх?