Когда вызывать glEnable (GL_FRAMEBUFFER_SRGB)?

У меня есть система рендеринга, в которой я рисую в FBO с мультисэмплированным буфером рендеринга, а затем копирую его в другой FBO с текстурой, чтобы разрешить выборки, чтобы прочитать текстуру для выполнения затенения постобработки при рисовании в задний буфер ( Индекс FBO 0).

Теперь я хотел бы получить правильный вывод sRGB ... Проблема в том, что поведение программы довольно несовместимо между тем, когда я запускаю ее в OS X и Windows, и это также меняется в зависимости от машины: В Windows с Intel HD 3000 он не будет применять нелинейность sRGB, но на другой моей машине с Nvidia GTX 670 он применяется. На Intel HD 3000 в OS X это тоже применимо.

Это, вероятно, означает, что я не устанавливаю свое GL_FRAMEBUFFER_SRGB состояние включения в нужных точках программы. Однако я не могу найти никаких руководств, которые на самом деле говорят мне, когда я должен его включить, они только упоминают, что это очень просто и не требует затрат на производительность.

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

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

Не знаю, правильно это или нет. Это, безусловно, применяет нелинейность к цветам, но я не могу сказать, применяется ли это дважды (что было бы плохо). Он может применить гамму, как я рендерю к моему первому FBO. Он мог бы сделать это, когда я преобразовал первый FBO во второй FBO. Почему нет?

Я зашел так далеко, что сделал снимки экрана своего последнего кадра и сравнил необработанные значения цвета пикселей с цветами, которые я установил для них в программе:

Я установил входной цвет на RGB (1,2,3), а на выходе - RGB (13,22,28).

Это похоже на довольно сильное сжатие цвета на нижнем уровне и заставляет меня задаться вопросом, применяется ли гамма несколько раз.

Я только что рассмотрел уравнение sRGB и могу убедиться, что преобразование, похоже, применяется только один раз, поскольку линейные 1/255, 2/255 и 3/255 действительно сопоставляются с sRGB 13/255, 22/255 и 28/255 с использованием уравнения 1.055*C^(1/2.4)+0.055. Учитывая, что расширение настолько велико для этих низких значений цвета, действительно должно быть очевидно, применяется ли преобразование цвета sRGB более одного раза.

Итак, я до сих пор не определил, что мне делать правильно. glEnable(GL_FRAMEBUFFER_SRGB) применяется только к окончательным значениям буфера кадра, и в этом случае я могу просто установить это во время процедуры инициализации GL и забыть об этом в дальнейшем?


person Steven Lu    schedule 08.07.2012    source источник


Ответы (1)


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

Любая запись в изображения, не в формате sRGB, не должна подвергаться влиянию. Поэтому, если вы пишете изображение с плавающей запятой, ничего не должно происходить. Таким образом, у вас должна быть возможность просто включить его и оставить так; OpenGL будет знать, когда вы выполняете рендеринг в фреймбуфер sRGB.

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

Что касается этого:

В Windows с Intel HD 3000 нелинейность sRGB не применяется.

Это почти наверняка из-за того, что Intel отстой при написании драйверов OpenGL. Если при включении GL_FRAMEBUFFER_SRGB он делает что-то неправильно, то это из-за Intel, а не из-за вашего кода.

Конечно, также может быть, что драйверы Intel не предоставили вам изображение sRGB с самого начала (если вы выполняете рендеринг в буфер кадра по умолчанию).

person Nicol Bolas    schedule 08.07.2012
comment
Ну вот в чем дело. Когда я включаю GL_FRAMEBUFFER_SRGB при инициализации и не касаюсь его навсегда, даже на Intel HD 3000 в Windows он выполнит правильное преобразование. Просто, похоже, требуется, чтобы он был включен для большей части пути кода, чем на Nvidia. - person Steven Lu; 09.07.2012
comment
То, что вы сказали, имеет большой смысл, что формат буферов sRGB должен определять, записываются ли в них значения sRGB. Я протестирую это, чтобы увидеть, правильно ли это реализовано, и это определенно позволит мне получить намного больше от 8 бит на канал. Я надеюсь, что шаг разрешения мультисэмплов также делает это правильно: я встречал некорректные результаты мультисэмплового разрешения раньше, но, возможно, в то время я работал в неправильном режиме. (см. этот раздел opengl.org/discussion_boards/showthread.php/) - person Steven Lu; 09.07.2012
comment
Поддерживает ли Intel драйверы OpenGL для своих процессоров на компьютерах Apple? У меня создалось впечатление, что Apple все написала сама (что, по моему опыту, объясняет, почему в их драйвере AMD так много ошибок). - person Philip Guin; 02.04.2015