Компьютерная графика

Пост-обработка: Bloom, DoF, Motion Blur, Tone Mapping

Cyberpunk 2077 в момент выхода в 2020 году продал 13 миллионов копий за 10 дней - рекорд для PC. Критики отмечали кинематографичность визуала. За этим стоит не более детализированная геометрия, а пост-обработка: HDR Bloom, Bokeh DoF, ACES tone mapping. Одни и те же полигоны с пост-процессингом и без выглядят как разные игры.

  • Cyberpunk 2077: Bloom + ACES tone mapping дают неоновые огни без пересвета на улицах Найт-Сити
  • God of War: кинематографический DoF с hexagonal bokeh на портретных сценах в реальном времени
  • Unreal Engine 5: Temporal Super Resolution с motion blur velocity buffer для 4K из 1080p
  • Horizon Forbidden West: per-object motion blur для персонажей через отдельный skinned velocity pass

Bloom: почему яркий свет светится

Матрица камеры физически не может передать диапазон яркостей солнечного дня - 100 000 : 1 против 255 : 1 у SDR-экрана. Bloom не «добавляет свечение» - он имитирует оптическое рассеяние в линзе, которое происходит именно тогда, когда сцена в HDR.

**Пайплайн Bloom:** 1) рендер сцены в HDR-буфер (16f RGB); 2) threshold-pass - выбрать пиксели с яркостью > 1.0; 3) downscale до 1/2, 1/4, 1/8, 1/16; 4) двойной Gauss blur (сначала по X, затем по Y) на каждом mip; 5) upscale с additive blend обратно в full-res; 6) сложить с оригиналом перед tone mapping. Разделённый Gauss (2 прохода по 1D) даёт O(n) вместо O(n²) для 2D-ядра.

**Dual Kawase vs Gauss.** Unreal Engine 4 использует Dual Kawase blur вместо Gauss - он требует вдвое меньше текстурных выборок при схожем результате. Принцип: каждый downscale-pass читает 4 соседних пикселя со смещением +0.5, что даёт Gauss-подобное размытие без явного ядра.

Почему Gaussian blur при Bloom разбивается на два прохода - по X и по Y?

Depth of Field: размытие по кругу рассеяния

В реальной камере объекты вне фокусной плоскости проецируются не в точку, а в диск - Circle of Confusion (CoC). Чем больше диск, тем сильнее объект размыт. GPU-DoF воспроизводит эту геометрию, используя глубину из G-буфера.

**Gather vs Scatter DoF.** Gather: каждый пиксель собирает вклады из радиуса CoC (описан выше). Scatter: каждый яркий пиксель «разбрасывает» bokeh-диски на соседей - физически точнее, но требует vertex shader instancing и alpha blend без depth test. Unreal Engine 5 использует Scatter для ярких источников света и Gather для фона.

Что такое Circle of Confusion (CoC) в контексте Depth of Field?

Motion Blur: размытие движения из velocity-буфера

Без motion blur анимация в 30 fps выглядит дёрганой даже на быстром GPU - каждый кадр слишком чёткий. Реальная камера интегрирует свет за время выдержки (1/60 с), смазывая движущиеся объекты. GPU имитирует это за один пост-процессинг проход.

**Screen-Space Velocity Buffer.** Во время G-буфер прохода вершинный шейдер вычисляет разницу между текущей и предыдущей позицией каждого пикселя в NDC: `velocity = (currentNDC - prevNDC) * 0.5`. Пост-процессинг шейдер читает velocity-вектор и делает N выборок вдоль него, усредняя цвет. Количество выборок = 8..16 для игр, 32+ для кинематографии.

**Per-object vs camera motion blur.** Velocity buffer из NDC-разницы автоматически учитывает и движение камеры, и движение объектов. Но скинированные персонажи требуют velocity от каждой кости. Unreal Engine хранит отдельный skinned velocity буфер для Skeletal Mesh - это дополнительный geometry pass, но критичен для корректного blur'а персонажей.

Как velocity buffer используется для motion blur?

Tone Mapping: из HDR в то, что видит экран

После Bloom, DoF и Motion Blur HDR-буфер содержит значения яркости от 0 до 10 000 нит. Экран показывает 0..255. Tone mapping - это нелинейное сжатие этого диапазона с сохранением деталей в тенях и светах. Без него весь bright region становится белым, весь dark region - чёрным.

**ACES и Display-P3.** ACES (Academy Color Encoding System) разработан киноиндустрией в 2014 году. Epic Games перевела Unreal Engine на ACES в UE4.15. Современные iPhone используют Display-P3 (DCI-P3 с D65) - цветовое пространство шире sRGB на 25%. Для корректного рендеринга нужно знать целевое пространство ещё до tone mapping.

Tone mapping и gamma correction - одно и то же

Tone mapping сжимает HDR в LDR с учётом перцептивных характеристик (S-кривая). Gamma correction переводит линейное пространство в sRGB (степень 1/2.2). Это разные операции: сначала tone mapping, потом gamma.

Ошибка приводит к тому, что яркие блики становятся белыми без деталей (пересвет), а тени теряют контраст. ACES + gamma дают кинематографичный результат, Reinhard без gamma - плоский и бледный.

Зачем нужен tone mapping и где он применяется в пайплайне?

Ключевые идеи

  • Bloom: HDR threshold -> downscale mip chain -> двойной 1D Gauss (сепарабельный, O(n)) -> additive upscale
  • DoF: Circle of Confusion из глубины G-буфера -> gather N выборок по CoC-радиусу (hexagonal bokeh)
  • Motion Blur: velocity = текущий NDC - предыдущий NDC -> N выборок вдоль вектора -> усредение
  • Tone Mapping: последний шаг - сжать HDR в LDR с S-кривой (ACES) -> gamma correction -> экран
  • Порядок пайплайна: G-buffer -> lighting HDR -> Bloom -> DoF -> Motion Blur -> Tone Mapping -> gamma

Связанные темы

Пост-обработка завершает HDR пайплайн, начатый в Deferred Rendering.

  • Deferred Rendering — G-буфер с глубиной и velocity - фундамент всех пост-эффектов
  • GPU Graphics Pipeline — Fullscreen quad render target - базовая техника всех пост-процессинг шейдеров
  • Terrain и LOD — Terrain рендерится в тот же HDR-буфер и проходит через тот же пост-пайплайн

Вопросы для размышления

  • Почему Bloom нужно применять до tone mapping, а не после? Что изменится если поменять порядок?
  • Как Temporal Anti-Aliasing использует тот же velocity buffer, что и motion blur, но для разной задачи?
  • ACES - стандарт киноиндустрии. Какие компромиссы у него есть по сравнению с Reinhard для игр с яркими HUD-элементами?

Связанные уроки

  • cg-14 — Deferred Rendering даёт G-буфер, на котором строятся все пост-эффекты
  • cg-08 — Compute шейдер и текстурный пайплайн - основа всех fullscreen-эффектов
  • cg-16 — Terrain LOD завершает пайплайн с тем же HDR-буфером
  • dsp-04 — Bloom и DoF - это свёрточные фильтры: Гаусс и bokeh-ядро из теории ЦОС
  • arch-09-cache
Пост-обработка: Bloom, DoF, Motion Blur, Tone Mapping

0

1

Войти