Ответ 1
Примечание. В следующем обсуждении предполагается, что вы понимаете, что такое цветовое пространство sRGB, что такое гамма-коррекция, что такое линейное цветовое пространство RGB и т.д. Основное внимание уделяется реализации технологии OpenGL.
Если вы хотите подробно обсудить эти темы, я бы посоветовал взглянуть на мои учебные пособия по коррекции HDR/гамма (для понимания линейных цветовых пространств и гаммы), а также учебный курс по изображениям sRGB и тому, как они справляются с гамма-коррекцией.
Во-первых, может ли кто-нибудь подтвердить на моем скриншоте, что это то, что вы ожидаете увидеть?
Я не уверен, что понимаю, что вы имеете в виду под этим вопросом. Если вы примените правильную гамма-коррекцию (то, что sRGB делает более или менее), вы, как правило, получите больше деталей в более темных областях изображения и "более яркий" результат.
Тем не менее, правильный способ думать о том, что до тех пор, пока вы не сделаете правильную гамма-коррекцию, все ваши изображения будут неправильными. Ваши изображения были слишком темными, и гамма-коррекция теперь делает их соответствующей яркости. Каждое принятое вами решение о том, какими должны быть цвета и каким должен быть яркий свет, было неверным.
Второй вопрос, который я хотел бы задать, - в какой момент аппаратная коррекция фактически выполняется?
Это совсем другой вопрос, чем часть "например", которую вы продолжаете с обложками.
Изображения sRGB (помните: текстура содержит изображения, но у кадровых буферов тоже могут быть изображения) может использоваться в следующих контекстах:
-
Передача данных от пользователя непосредственно к изображению (например, с помощью glTexSubImage2D и пр.). OpenGL предполагает, что вы предоставляете данные, которые уже находятся в цветовом пространстве sRGB. Таким образом, нет перевода данных при загрузке. Это сделано потому, что это имеет смысл: обычно любое изображение, полученное от художника, будет находиться в цветовом пространстве sRGB, если художник не приложил много усилий, чтобы поместить его в какое-то другое цветовое пространство. Практически каждый графический редактор работает непосредственно в sRGB.
-
Чтение значений в шейдерах через сэмплеры (т.е. Доступ к текстуре). Это довольно просто. OpenGL знает, что тексельные данные в изображении находятся в цветовом пространстве sRGB. OpenGL предполагает, что шейдер хочет получить линейные данные цвета RGB. Следовательно, все попытки сэмплирования текстуры с форматом изображения sRGB приведут к конвертации sRGB-> lRGB. Что бесплатно, кстати.
И с другой стороны, если у вас есть аппаратное обеспечение с поддержкой GL 3. x+, вы почти наверняка выполните фильтрацию в линейном цветовом пространстве, где это имеет смысл. sRGB - это нелинейное цветовое пространство, поэтому линейная интерполяция значений sRGB всегда неверна.
-
Сохранение значений, выводимых из фрагментного шейдера, в изображения кадрового буфера. Это где это становится немного сложнее. Даже если изображение кадрового буфера, к которому вы рендерите, находится в цветовом пространстве sRGB, этого недостаточно для принудительного преобразования. Вы должны явно
glEnable(GL_FRAMEBUFFER_SRGB)
; это говорит OpenGL, что значения, которые вы пишете из своего фрагментного шейдера, являются линейными значениями цветового пространства. Поэтому OpenGL необходимо преобразовать их в sRGB при сохранении их в изображении.Опять же, если у вас есть оборудование GL 3. x+, вы почти наверняка получите смешивание в линейном цветовом пространстве. То есть OpenGL будет считывать значение sRGB из кадрового буфера, преобразовывать его в линейное значение RGB, смешивать его с входящим линейным значением RGB (которое вы записали из своего шейдера), преобразовывать смешанное значение в цветовое пространство sRGB и сохранять его, Опять же, это то, что вы хотите; смешивание в цветовом пространстве sRGB всегда плохо.
Теперь, когда мы это понимаем, давайте посмотрим на ваш пример.
Например, я записываю фреймы в FBO, а затем я рендерирую четырехугольник размером с экран в задний буфер с использованием цветового буфера FBO (я собираюсь в ближайшее время переключиться на отложенное затенение).
Проблема в том, что вы не задаете правильные вопросы. Что вам нужно иметь в виду, особенно когда вы переходите к отложенному рендерингу, это вопрос:
Это линейный RGB или нет?
В общем, вы должны как можно дольше хранить любые промежуточные данные в гамма-правильном пространстве. Поэтому любые промежуточные буферы (т.е. где вы накапливаете свои источники света) не должны быть sRGB.
Это не о стоимости преобразования; это действительно о том, что вы делаете. Если вы делаете отложенный рендеринг, то, вероятно, вы также делаете освещение HDR и так далее. Таким образом, ваш буфер накопления света должен быть с плавающей точкой. И плавающие буферы всегда линейны; нет никаких причин, чтобы они не были линейными.
Ваше конечное изображение, кадровый буфер по умолчанию, должно быть sRGB, если вы хотите воспользоваться бесплатной гамма-коррекцией (и вы это делаете). Если вы выполняете всю свою работу в плавающих буферах HDR, а затем отображаете результаты в тон для окончательного отображения, вы должны записать это в изображение sRGB.