Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            Документация для продвинутых пользователей
                Гамма-коррекция или sRGB-конвейер

Гамма-коррекция или sRGB-конвейер

Опубликованно: 30.05.2017, 12:04
Последняя редакция, Andry: 01.06.2017 13:52

Обзор

Вот краткий обзор того, что понимается под термином «Гамма-коррекция(Gamma Correction)».
Более подробные выводы по этому вопросу можно найти здесь: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html и здесь http://www.arcsynthesis.org/gltut/Texturing/Tutorial%2016.html

Мы считаем, что значения цвета являются линеарными при вычислении освещения. Что это значит? Это означает, что мы предполагаем, что цвет 0,5,0,5,0,5 на полпути между черным и белым.
Проблема в том, что это не так, или, по крайней мере, нет, когда вы смотрите на цвет через монитор.
ЭЛТ-мониторы имели физические ограничения, которые мешали им иметь линеарный способ представления цветов. Это означает, что 0,5,0,5,0,5 через монитор не на полпути между черным и белым (темнее). Обратите внимание, что черно-белое изображение остается тем же.
Если мы не принимаем это во внимание, то сделанные изображения слишком темнеют и кажутся скучными.
ЖК-мониторы по-прежнему имитируют это физическое ограничение (думаю, для обратной совместимости).
Выведите правильные цвета
Гамма-коррекция(Gamma Correction) — это метод, который имеет тенденцию исправлять проблему. Гамма — коэффициент мощности, применяемый к цвету монитором при освещении пикселя на экране (или, по крайней мере, упрощение применяемой функции). Поэтому, когда мы выводим цвет, мы должны применить обратную силу этого коэффициента для аннулирования эффекта: finalColor = pow (compulatedColor, 1 / gamma);

Зная, какие цвета у нас есть в качестве входных данных
Другим аспектом гамма-коррекции являются цвета, которые мы получаем как входные данные в процессе рендеринга, которые хранятся в текстурах или в цветовых параметрах ColorRGBA. Почти все редакторы изображений сохраняют цветовые данные в изображениях, которые уже гамма исправлены (чтобы цвета были правильными, когда вы показываете изображение в браузере). Также большинство цветов, выбранных вручную (в наборе цветов), можно принять за гамма-коррекцию, поскольку вы, скорее всего, выбрали этот цвет с помощью монитора. Такие изображения или цвет, как говорят, находятся в пространстве цветности sRGB, что означает «стандартный RGB» (который не считается стандартным). Это означает, что текстуры и цвета, которые мы используем в качестве вклада в наши шейдеры, не находятся в линеарном пространстве. Проблема в том, что мы нуждаемся в них в линеарном пространстве, когда вычисляем освещение, иначе освещение ошибочно. Чтобы избежать этого, нам нужно применить некоторую гамма-коррекцию к цветам: (pow(color, gamma), это применимо только к текстурам, которые будут отображать цвета на экране (в основном диффузные карты, зеркальные, световые карты). Карты Нормали, картам высот не нуждаются в коррекции.

Это та разница, которую вы можете иметь:
Левый — не исправленный выход, Правый — гамма-исправленный выход.

gamma_corrected

Реализация

  • Чтобы обрабатывать правильно гамма-коррекцию цветов вывода, Opengl предоставляет расширение ARB, которое позволяет выводить цвет в линеарном пространстве и автоматически его корректировать: https://www.opengl.org/registry/specs/ARB/framebuffer_sRGB.txt
  • Для обработки ввода вместо классического формата изображения RGBA8 можно использовать SRGB8_ALPHA8_EXT, который является в основном RGBA в sRGB. Используя его, вы указываете графическому процессору, что текстура находится в пространстве sRGB, и при выборе цветности из него графический процессор линеаризует значение цветности для вас (бесплатно). Есть sRGB, эквивалентный всем 8-битным форматам (даже сжатый формат, такой как DXT).
  • Но все текстуры не нужны. Например, карты нормалей, карты высот цветов, скорее всего, сгенерированы, а не вручную выбраны художником, просматривающим монитор. Реализация должна учитывать это и раскрывать способ исключения некоторых текстур из конвейера sRGB.

Гамма-коррекция в jME 3.0 основана на этих трех утверждениях.

Обратите внимание, что Gamma Correction доступна только на рабочем столе с LWJGL или JOGL-рендерером. Они пока не поддерживаются на устройствах Android или iOS.

Гамма-коррекции включение/отключение

Вы можете включить и отключить гамма-коррекцию с помощью AppSettings. Существует метод setGammaCorrection(boolean), который изменяет настройку. Используйте это в main() методе вашего приложения:

AppSettings settings = new AppSettings(true);
settings.setGammaCorrection(true);
app.setSettings(settings);

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

dialog_displayed

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

Включение вывода Гамма-коррекция

Вы можете включить или отключить гамма-коррекцию обработанного вывода с помощью:

renderer.setMainFrameBufferSrgb(boolean srgb)

Это будет проигнорировано, если на оборудовании нет GL_ARB_framebuffer_sRGB или GL_EXT_texture_sRGB. Это можно переключать во время выполнения.

Это использует гамма-коррекцию оборудования Opengl, которая использует приблизительное значение Гамма 2.2 и использует следующую формулу: color = pow(color,1/gamma)

Это не даст точных результатов, так как реальная гамма может меняться в зависимости от монитора.
Если это проблема, обратитесь к разделу «Обработка гамма-коррекции в разделе после обработки».

Включение линеаризации текстур

Вы можете включить или отключить линеаризацию текстур, используя

renderer.setLinearizeSrgbImages(boolean linearize)

Это будет проигнорировано, если на оборудовании нет GL_ARB_framebuffer_sRGB или GL_EXT_texture_sRGB.

Переключение этого параметра во время выполнения приведет к неожиданному поведению. Для изменения этого параметра потребуется надлежащая перезагрузка контекста для работы.

Все изображения, отмеченные в пространстве цветности как sRGB, будут загружены на графический процессор с использованием формата изображения sRGB. Линеаризация аппаратной текстуры Opengl также использует приблизительное значение Гамма 2.2 и линеаризует выбранный цвет текселя, используя следующую формулу: color = pow(color, gamma)
Как и в случае вывода гамма-коррекции, это не даст точного результата, но ошибка менее важна, поскольку большинство редакторов изображений используют то же приближение для правильных изображений и сохраняют их в пространстве цветности sRGB.

Не все форматы изображений имеют эквивалент sRGB и только 8-битный формат. Вот исчерпывающий список поддерживаемого формата и эквивалентов:

  • RGB8 : GL_SRGB8
  • RGBA8 : GL_SRGB8_ALPHA8
  • BGR8 : GL_SRGB8
  • ABGR8 : GL_SRGB8_ALPHA8
  • Luminance8 : GL_SLUMINANCE8
  • Luminance8Alpha8 : GL_SLUMINANCE8_ALPHA8
  • DXT1 : GL_COMPRESSED_SRGB_S3TC_DXT1
  • DXT1A : GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1
  • DXT3 : GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3
  • DXT5 : GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5
Обычно только каналы rgb гамма-коррекции, поскольку альфа-канал не представляет собой значение цвета

Исключение изображений из sRGB-конвейера

Только загруженные изображения будут помечены в пространстве цветности как sRGB, при использовании assetManager.loadTexture или loadAsset.
Пространство цветности изображения, созданное кодом, должно быть указано в конструкторе или будет приниматься как Linear, если не указано.

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

Невозможно определить реальное пространство цветности изображения сразу при загрузке, поэтому мы должны вывести пространство цветности из применения сразу при загрузки вами. Применение продиктовано материалом, к этим текстурам примененным, и по параметрам материала, которые у него заданы. Можно задавать в файле описания материала (j3md), что параметры текстуры должены быть приняты как в линеарном пространстве цветности и, следовательно, не должены линеаризоваться, используя ключевое слово -LINEAR рядом с параметром (случай не имеет значения).

Например, вот как объявлен параметр NormalMap в описании освещеаемого материала.

 // Карта нормалей
 Texture2D NormalMap -LINEAR

Когда текстуре присваивается этот параметр материала, используя material.setTexture(“NormalMap, myNormalTexture), пространство цветности изображения этой текстуры будет принудительно линеарным. Поэтому, если вы создаете свой собственный материал и хотите использовать Гамма-коррекцию, убедитесь, что вы правильно отмечаете у своих текстур, правильное пространство цветности.

Это может показаться сложным, но вам просто нужно ответить на такой вопрос: отображает ли мое изображение цветовые данные? Если ответ отрицательный, тогда вы должны установить флаг -Linear.

ColorRGBA как sRGB

Атрибуты r, g, b объекта ColorRGBA ВСЕГДА предполагаются в Linear пространстве цветности.

Если вы хотите установить цвет, который вы выбрали в выборе цвета, вы должны использовать метод setAsSRGB для ColorRGBA. Это преобразует данные в линеарном пространстве цветности, используя ту же формулу, что и раньше: color = pow (color, gamma), где gamma = 2.2;

Если вы хотите получить эти значения из ColorRGBA, вы можете вызвать метод getAsSRGB. Значения будут преобразованы обратно в пространство цветности sRGB.

Возвращаемым типом этого метода является Vector4f, а не ColorRGBA, поскольку, как указано ранее, все атрибуты ColorRGBA r, g, b принимаются в Linear пространство цветности.

Обработка обработанного вывода Gamma Correction с фильтром постобработки

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

В этом конкретном случае вы можете сделать следующее:

  1. Включить глобальную настройку настройки гамма-коррекции.
  2. Отключить обработанную выходную коррекцию: renderer.setMainFrameBufferSrgb (false); (Например, в методе simpleInit вашего SimpleApplication).
  3. Используйте GammaCorrectionFilter в FilterPostProcessor и установите для него правильное значение гаммы (по умолчанию — 2.2).

Должны ли вы использовать это?

Да. В основном потому что, это единственный способ иметь правильное освещение. Если вы начинаете новый проект, это не проблема … используйте его, периодически. И не позволяйте игроку отключить его.

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


Переведено для jmonkeyengine.ru, оригинал
Автор перевода: Andry

Добавить комментарий

jMonkeyEngine.ru © 2017. Все права сохранены.