Вперед рендеринг нескольких проходов рендеринга - PullRequest
0 голосов
/ 19 мая 2018

Я пытаюсь внедрить PBR в свой простой рендерер OpenGL и пытаюсь использовать несколько проходов освещения, я использую один проход на свет для рендеринга следующим образом:

1- Первый проход = глубина

2- Второй проход = окружающий

3- [3 .. n] для всех источников света в сцене.

Я использую функцию смешивания glBlendFunc (GL_ONE, GL_ONE) для проходов [3..n], и я делаю гамма-коррекцию в конце каждого фрагментного шейдера.

Но у меня все еще есть проблема с выходным изображением, оно выглядит особенно шумно, особенно когда я использую карты текстур.

Что-то не так с этими шагами или есть какое-то улучшение в этом процессе?

1 Ответ

0 голосов
/ 21 мая 2018

Итак, в общем, вы рассчитываете

f(x) = a^gamma + b^gamma + ...

Однако, что вы действительно хотите (и, как уже отмечалось @NicolBolas в комментариях), это

g(x) = (a + b + ...)^gamma

Теперьf(x) и g(x) будут равняться друг другу только в довольно бесполезных случаях, таких как gamma=1.Вы просто не можете аддитивно разложить нелинейную функцию, такую ​​как мощность, таким образом.

Правильное решение состоит в том, чтобы смешать все вместе в линейном пространстве и затем выполнить гамма-коррекцию на общую сумму линейных вкладов каждого источника света..

Однако реализация этого приведет к нескольким техническим проблемам.Во-первых, стандартные 8 бит на канал просто недостаточно точны для хранения линейных значений цвета.Использование такого формата для этапа накопления приведет к появлению ярко видимых артефактов цветовых полос.Есть два подхода для решения этой проблемы:

  1. Использовать более высокий бит-канальный формат для накопительного кадрового буфера.Вам понадобится отдельный проход гамма-коррекции, поэтому вам нужно настроить визуализацию на текстуру через FBO.GL_RGBA16F представляется особенно хорошим форматом для этого.Поскольку вы используете модель освещения PBR, вы также можете работать со значениями цвета за пределами [0,1], и вместо простой гамма-коррекции применить правильное отображение тонов в последнем проходе.Обратите внимание, что, хотя вам может не понадобиться альфа-канал, все равно используйте здесь формат RGBA, но форматы RGB просто не требуются для форматов цветовых буферов согласно спецификации GL, поэтому они могут не поддерживаться универсально.

  2. Сохранение данных в формате 8 бит на компонент с гамма-коррекцией.Ключевым моментом здесь является то, что смешивание все еще должно выполняться в линейном пространстве, поэтому значения цвета целевого кадрового буфера должны быть линеаризованы до смешивания.Это может быть достигнуто с помощью кадрового буфера с форматом GL_SRGB8_ALPHA8 и включением GL_FRAMEBUFFER_SRGB.В этом случае графический процессор автоматически применяет стандартную гамма-коррекцию sRGB при записи цвета фрагмента в кадровый буфер (что в настоящее время делает ваш фрагментный шейдер), но это также приведет к линеаризации sRGB при доступе к этим значениям, в том числе для смешивания.Спецификация профиля ядра ядра в разделе «17.3.6.1 Уравнение смешивания»:

    Если включен FRAMEBUFFER_SRGB и значение FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING для вложения кадрового буфера соответствуетв буфер назначения SRGB (см. раздел 9.2.3), значения цвета назначения R, G и B (после преобразования с фиксированной точкой в ​​плавающую) считаются закодированными дляцветовое пространство sRGB и, следовательно, должно быть линеаризовано до их использования при смешивании.Каждый компонент R, G и B преобразуется так же, как описано для компонентов текстуры sRGB в разделе 8.24.

Подход 1 будет намногоболее общий подход, в то время как подход 2 имеет несколько недостатков:

  • , линеаризация / делинеризация выполняется несколько раз, что может привести к потере некоторой вычислительной мощности графического процессора
  • из-за использования всего лишь 8 битцелое число, общее качество будет ниже.После каждого шага наложения результаты округляются до следующего представимого числа, поэтому вы получите намного больший шум квантования.
  • вы все еще ограничены значениями цвета в [0,1] и не можете (легко) делать большеинтересные эффекты тонального отображения и рендеринга HDR

Однако, подход 2 также имеет преимущества:

  • вам не нужен отдельный финальный проход гамма-коррекции
  • , есливаша платформа / оконная система поддерживает фрейм-буферы sRGB, вы можете напрямую создавать пиксельный формат / визуал sRGB для своего окна и вообще не требовать какого-либо шага рендеринга в текстуру.По сути, для этого достаточно запроса кадрового буфера sRGB и включения GL_FRAMEBUFFER_SRGB.
...