Преобразование sRGB OpenGL

Допустим, я загружаю текстуру из jpg-файла с цветовым профилем sRGB, и при загрузке не было преобразования в линейный RGB. Когда прямоугольник отображается на экране, я не вижу проблем с изображением. цвет такой же, как при открытии в одном из редакторов.

Вопрос, поскольку преобразования не было, значения RGB остались в диапазоне sRGB. Откуда аппаратное обеспечение знает, что преобразование не требуется или почему оно не было преобразовано графическим процессором. В принципе, почему преобразования XYZ -> sRGB не произошло.

Я очень сбит с толку, поскольку, если я передам данные sRGB во что-то, что в конце концов снова преобразует их в sRGB, цвета изменятся, но это не так.


person Anton Stafeyev    schedule 21.01.2021    source источник
comment
преобразования в линейный RGB не было Откуда вы это знаете? Когда прямоугольник отображается на экране Как вы его отображаете?   -  person Nicol Bolas    schedule 21.01.2021
comment
@NicolBolas хорошо, я рисую четырехугольник с текстурой на нем. Без указания дополнительной информации о буфере кадров и самой текстуре. И если я подаю изображение sRGB во что-то, что ожидает linearRGB, я полагаю, что оно выполняет преобразование профиля при отображении на мониторе srgb справа. Поэтому цвета будут другими, я думаю?   -  person Anton Stafeyev    schedule 21.01.2021
comment
Указывали ли вы где-нибудь ввод или вывод SRGB (например, в текстурах или буферах кадров)? В противном случае OpenGL не будет выполнять никаких преобразований.   -  person Nico Schertler    schedule 21.01.2021


Ответы (1)


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

[RGB image|sRGB] -> [OpenGL Window Buffer|sRGB] -> [Monitor|sRGB]

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

Теперь рассмотрим другой сценарий: вы применяете Исходное изображение для наложения текстуры на 3D-объект с включенным освещением. Уравнение освещения имеет смысл только в линейных цветовых пространствах RGB, поэтому без дополнительной настройки OpenGL будет в основном брать нелинейные значения изображения sRGB, передавать их в качестве параметров уравнениям затенения без изменений и записывать результат в буфер окна OpenGL, который будет передан на монитор, настроенный на цветовое пространство sRGB. Результат будет доступным, но физически некорректным.

Чтобы решить проблему с неправильным освещением, в OpenGL введены функции sRGB-awareness, так что пользователь может явно указать, находится ли входное изображение в цветовом пространстве sRGB или линейном RGB, и если результат Значения цвета программы GLSL должны быть неявно преобразованы из линейного цветового пространства RGB в нелинейное цветовое пространство sRGB. Так что:

[GLSL Texture Input|sRGB -> linear RGB implicit conversion] ->
 -> [GLSL Lighting Equation|linear RGB] ->
 -> [GLSL output|linear RGB -> sRGB implicit conversion]

Шаги с неявным преобразованием будут выполняться ТОЛЬКО в том случае, если OpenGL был явно настроен таким образом, используя формат текстуры GL_SRGB8_ALPHA8 и используя GL_FRAMEBUFFER_SRGB при рендеринге в закадровый или оконный буфер. Вся концепция может быть сложной для понимания и даже более сложной реализовать.

Обратите внимание, что в данном контексте линейный RGB на самом деле означает линеаризованное цветовое пространство sRGB, поскольку часто опускается то, что на самом деле означает линейный RGB. Это связано с тем, что для математики цвета (освещения и прочего) важно только, чтобы значения RGB были линейными на входе и выходе в любом линейном цветовом пространстве, но когда речь идет о неявном sRGB —› linear RGB и linear RGB — › Преобразование sRGB — они явно основаны на преобразовании значений RGB, определенных спецификациями sRGB и OpenGL. На самом деле существует больше линейных цветовых пространств RGB, которые не представляют цветовое пространство sRGB.

Теперь учтите, что ваш Input Image не находится в цветовом пространстве sRGB, а использует какой-то другой цветовой профиль RGB. OpenGL не предоставляет много других форматов текстур, кроме линейного RGB и sRGB, поэтому правильное преобразование такого изображения в цветовое пространство sRGB должно выполняться программой чтения изображений или специальной программой GLSL, выполняющей преобразование цветового пространства на лету.

Теперь рассмотрим Монитор, настроенный на профиль, отличный от sRGB, например AdobeRGB. В этом случае передача sRGB-изображения в окно OpenGL приведет к искажению цветов. Сообщив Windows, что ваш монитор находится в другом цветовом профиле, вы поможете некоторым приложениям, таким как Photoshop, правильно преобразовывать цвета, но OpenGL ничего не знает об этих цветовых профилях, настроенных в Windows! Это приложение, которое отвечает за применение информации о цветовом профиле для выполнения правильного преобразования цвета (с помощью специальных программ GLSL или другими средствами). Работая с Входным изображением в цветовом пространстве, отличном от sRGB, приложение также будет иметь альтернативу для выполнения преобразования non-sRGB -> sRGB -> another non-sRGB цветов или реализации программы GLSL, которая будет выполнять преобразование цветов без прокси sRGB (или через прокси XYZ) непосредственно в целевое цветовое пространство, чтобы избежать потери информации о точности цвета из-за переходных преобразований.

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

Например, macOS определяет NSWindow::setColorSpace property, что позволяет приложению явно указывать, в каком цветовое пространство заполняется Window Buffer, поэтому система сама выполняет необходимое преобразование в фактический цветовой профиль монитора. Система Android определяет аналогичный интерфейс для поддержки нового цветового профиля дисплея P3. с расширенным цветовым диапазоном по сравнению со старым цветовым профилем sRGB. Это подразумевает, однако, что средство визуализации OpenGL на самом деле знает, как выводить результат в этом конкретном цветовом пространстве - это другая тема (есть также набор дополнительных расширений OpenGL, помогающих разработчикам в этом направлении)... До сих пор я не слышал о аналогичный API в Windows, но я мог что-то упустить.

person gkv311    schedule 21.01.2021