Я полагал, что мой гамма-корректур должен быть следующим:
- Используйте sRGB-формат для всех загруженных текстур (
GL_SRGB8_ALPHA8
), так как все художественные программы pre-gamma исправляют свои файлы. Когда выборка из текстурыGL_SRGB8_ALPHA8
в шейдере OpenGL автоматически преобразуется в линейное пространство. - Выполняйте все вычисления освещения, постобработку и т.д. в линейном пространстве.
- Преобразуйте обратно в пространство sRGB при записи окончательного цвета, который будет отображаться на экране.
Обратите внимание, что в моем случае окончательная запись цвета включает в себя запись из FBO (которая является линейной текстурой RGB) в задний буфер.
Мое предположение было поставлено под сомнение, как если бы я исправился на последней стадии, мои цвета ярче, чем они должны быть. Я установил для сплошного цвета мои ярлыки значения {255, 106, 0}, но когда я делаю рендеринг, я получаю {255, 171, 0} (как определено путем отпечатка и выбора цвета). Вместо оранжевого я становлюсь желтым. Если я не гамма корректировать на последнем шаге, я получаю точно правильное значение {255, 106, 0}.
В соответствии с некоторыми ресурсами современные ЖК-экраны имитируют CRT-гамму. Всегда ли они? Если нет, то как я могу сказать, правильно ли гамма? Я ошибаюсь где-то в другом месте?
Изменить 1
Теперь я заметил, что даже если цвет, который я пишу со светом, правильный, места, где я использую цвета из текстур, являются неправильными (но довольно темными, как я ожидал бы без гамма-коррекции). Я не знаю, откуда это неравенство.
Изменить 2
После использования GL_RGBA8
для моих текстур вместо GL_SRGB8_ALPHA8
все выглядит идеально, даже если вы используете значения текстуры при вычислениях освещения (если я половину интенсивности света, то значения выходного цвета являются половинными).
Мой код больше не учитывает гамма-коррекцию, и мой вывод выглядит правильно.
Это меня еще больше смущает, гамма-коррекция больше не нужна/используется?
Изменить 3 - В ответ на ответ datenwolf
После нескольких экспериментов я смущен на пару баллов.
1 - Большинство форматов изображений хранятся не линейно (в пространстве sRGB)
Я загрузил несколько изображений (в моем случае как изображения .png, так и .bmp) и проверил необработанные двоичные данные. Мне кажется, что изображения на самом деле находятся в цветовом пространстве RGB, как если бы я сравнивал значения пикселей с программой редактирования изображений с массивом байтов, которые я получаю в своей программе, они отлично сочетаются. Поскольку мой редактор изображений дает мне значения RGB, это указывает на изображение, сохраненное в RGB.
Я использую stb_image.h/.c для загрузки моих изображений и последовали за ним полностью, загрузив .png и не увидев нигде, что он гамма исправил изображение во время загрузки. Я также изучил .bmps в шестнадцатеричном редакторе и значения на диске, соответствующие им.
Если эти изображения фактически хранятся на диске в линейном пространстве RGB, как я должен (программно) знать, когда указывать изображение в пространстве sRGB? Есть ли способ запросить это, чтобы обеспечить более полнофункциональный загрузчик изображений? Или это зависит от создателей образа, чтобы сохранить их изображение в качестве гамма-коррекции (или нет), что означает установление соглашения и последующее за ним для данного проекта. Я спросил пару художников, и никто из них не знал, что такое гамма-коррекция.
Если я укажу, что мои изображения являются sRGB, они слишком темные, если я не исправим гамма в конце (что было бы понятно, если вывод монитора с использованием sRGB, но см. пункт № 2).
2 - "На большинстве компьютеров эффективный сканирование LUT является линейным! Что это значит?"
Я не уверен, что смогу найти, когда эта мысль будет завершена в вашем ответе.
Из того, что я могу сказать, экспериментируя, все мониторы, которые я тестировал на выходных линейных значениях. Если я нарисую полноэкранный квадрат и покрась его с жестко закодированным значением в шейдере с гамма-коррекцией нет, монитор отобразит правильное значение, которое я указал.
Какое предложение, которое я цитировал выше из вашего ответа и моих результатов, заставит меня поверить, что современные мониторы выводят линейные значения (т.е. не эмулируют ЭЛТ-гамма).
Целевая платформа для нашего приложения - ПК. Для этой платформы (исключая людей с ЭЛТ или действительно старых мониторов) было бы разумно делать все, что ваш ответ на # 1 есть, а для правильной гаммы # 2 до не (т.е. Не выполнять окончательный RGB → преобразование sRGB - либо вручную, либо используя GL_FRAMEBUFFER_SRGB)?
Если это так, каковы платформы, на которых подразумевается GL_FRAMEBUFFER_SRGB (или где он будет действителен для ее использования в настоящее время), или же мониторы, которые используют линейный RGB, действительно, что новый (учитывая, что GL_FRAMEBUFFER_SRGB был введен 2008)?
-
Я разговаривал с несколькими другими графическими разработчиками в своей школе и по звукам этого, ни один из них не учитывал гамма-коррекцию, и они не заметили ничего неправильного (некоторые даже не знали об этом). Один из разработчиков, в частности, сказал, что он получил неправильные результаты, принимая гамму, поэтому он решил не беспокоиться об гамме. Я не уверен, что делать в моем проекте для моей целевой платформы, учитывая противоречивую информацию, которую я получаю в сети/вижу с моим проектом.
Изменить 4 - В ответ на обновленный ответ datenwolf
Да, действительно. Если где-то в цепочке сигналов применяется нелинейное преобразование, но все значения пикселей не изменяются от изображения к дисплею, то эта нелинейность уже была предварительно применена к значениям пикселей изображения. Это означает, что изображение уже находится в нелинейном цветовом пространстве.
Ваш ответ имел бы смысл для меня, если бы я рассматривал изображение на моем дисплее. Чтобы быть уверенным, что я был ясен, когда я сказал, что изучаю массив байтов для изображения, я имею в виду, что я рассматривал числовое значение в памяти для текстуры, а не изображение, выводимое на экран (что я сделал сделать для точки # 2). Для меня единственным способом я мог видеть, что вы говорите, чтобы быть правдой тогда, является то, что редактор изображений давал мне значения в пространстве sRGB.
Также обратите внимание, что я попытался проверить вывод на мониторе, а также изменить цвет текстуры (например, разделив его на половину или удвоить), и результат оказался правильным (измеренный с использованием метода Я опишу ниже).
Как вы измерили реакцию сигнала?
К сожалению, мои методы измерения намного более грубые, чем ваши. Когда я сказал, что я экспериментировал на своих мониторах, я имел в виду, что я выводил сплошной цветной полноэкранный четырехъядерный цвет, чей цвет был жестко закодирован в шейдере для простого фреймбуфера OpenGL (который не делает никакого преобразования цветового пространства при написании). Когда я выводю белый, 75% серый, 50% серый, 25% серый и черный, отображаются правильные цвета. Теперь моя интерпретация правильных цветов, безусловно, может быть неправильной. Я беру скриншот, а затем использую программу редактирования изображений, чтобы увидеть, каковы значения пикселей (а также визуальная оценка, чтобы убедиться, что значения имеют смысл). Если я правильно понял, если бы мои мониторы были нелинейными, мне нужно было бы выполнить преобразование RGB- > sRGB, прежде чем представлять их на устройство отображения, чтобы они были правильными.
Я не собираюсь врать, я чувствую, что немного ухожу от своей глубины. Я думаю, что решение, которое я мог бы решить, для моей второй путаницы (окончательное преобразование RGB- > sRGB), будет настраиваемой настройкой яркости и по умолчанию соответствует тому, что выглядит правильно на моих устройствах (без гамма-коррекции).