Нужна ли выходная гамма-коррекция во фрагментном шейдере? - PullRequest
1 голос
/ 19 мая 2019

Когда I выводит цвет через fragColor в функции main() фрагментного шейдера, интенсивность цветовых компонентов интерпретируется как линейная RGB или sRGB? Или, другими словами, мне нужно выполнить гамма-коррекцию в моем шейдере или об этом уже позаботились?

Если общего ответа нет, но он зависит от какого-то свойства OpenGL: как мне установить это свойство?

Во избежание недопонимания: соответствующий цвет был сгенерирован полностью программно, нет текстур и т. П. (Что может потребовать ввод гамма-коррекция).

1 Ответ

3 голосов
/ 19 мая 2019

Каждый выходной фрагментный шейдер направляется на конкретное изображение в буфере кадров ( на основе glDrawBuffers состояние ). Это изображение имеет формат. Этот формат определяет интерпретацию цветового пространства по умолчанию для соответствующего вывода.

Поэтому, если вы записываете значение в изображение в линейном формате RGB, система интерпретирует это значение как линейное значение RGB. Если вы записываете значение в изображение в в формате sRGB , то система будет интерпретировать это значение как , уже равное в цветовом пространстве sRGB. Таким образом, преобразование не будет выполнено; это будет записано в текстуру как есть. И если смешивание активно, записанное вами значение sRGB будет смешано со значением sRGB на изображении в цветовом пространстве sRGB.

Теперь, когда дело доходит до записи в изображение цветового пространства sRGB, вы обычно не хотите такого поведения. Если у вас есть линейное значение RGB, вы хотите, чтобы система преобразовала это значение в цветовое пространство sRGB (а не притворялась, что оно уже есть). Не менее важно, что когда смешивание активно, вы хотите, чтобы значение в изображении sRGB было преобразовано в линейный RGB, затем смешано с линейным значением, записанным фрагментным шейдером, и, наконец, преобразовано обратно в sRGB. В противном случае смешивание дает результаты с сомнительной точностью.

Чтобы все это произошло, вы должны glEnable(GL_FRAMEBUFFER_SRGB). Когда эта функция включена, преобразование цветового пространства происходит для любого выходного фрагмента шейдера, записанного в любое изображение, цветовое пространство которого sRGB.

Это значение по умолчанию отключено.

Таким образом, если вы хотите записать линейные значения RGB и преобразовать их в sRGB для отображения, то вы должны:

  1. Убедитесь, что изображение кадрового буфера, в которое вы пишете, использует цветовое пространство sRGB. Для FBO это тривиально. Но если вы пишете в фрейм-буфер по умолчанию, то вам придется поработать с кодом инициализации OpenGL.

  2. Включите GL_FRAMEBUFFER_SRGB, если вы хотите использовать преобразование цветового пространства.

...