Использование гамма-коррекции

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

Что такое гамма и для чего он предназначен?

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

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

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

brightness( input ) = inputgamma

Гамма-значение обычно близко к значению 2,0. ЖК-мониторы и все другие новые технологии специально спроектированы для того, чтобы показать аналогичный ответ, поэтому все наше программное обеспечение и изображения не должны быть перекалибрированы для этих новых технологий. Стандарт sRGB объявляет, что это гамма-значение точно равно 2,2, и это значение стало широко реализованным стандартом.

Человеческий глаз также имеет функцию ответа, которая приблизительно инвертирует функцию питания CRT. Это означает, что воспринимаемая яркость пикселя резко увеличивается линейно вместе со значениями RGB в этом пикселе.

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

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

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

Фон гамма в Windows

Компьютеры Windows обычно имеют гамма-таблицу, которая представляет собой таблицу подстановки, которая принимает триплет байтов и выводит триплет байтов. Эти триплеты представляют собой 768 (256 x 3) байтов ОЗУ. Это нормально, если формат отображения содержит триплет значений БАЙТ RGB, но недостаточно выразителен для описания преобразований, которые могут потребоваться, если формат отображения имеет диапазон больше [0,1], например значения с плавающей запятой. ИНТЕРФЕЙСы API в Windows, управляющие гаммой, следуют эволюции, так как форматы отображения становятся все более сложными.

Первые API Windows, предлагающие гамма-управление, — это SetDeviceGammaRamp и GetDeviceGammaRamp интерфейса графических устройств Windows (GDI). Эти API работают с тремя 256-входными массивами WORD, при каждом кодировании WORD до одного, представленных значениями WORD 0 и 65535. Дополнительная точность WORD обычно недоступна в фактических таблицах подстановки оборудования, но эти API-интерфейсы должны были быть гибкими. Эти API, в отличие от других, описанных далее в этом разделе, допускают лишь небольшое отклонение от функции идентификации. На самом деле любая запись в пандусе должна находиться в пределах 32768 от значения идентификатора. Это ограничение означает, что ни один из приложений не может превратить экран полностью черным или другим нечитаемым цветом.

Следующий API — SetGammaRamp Microsoft Direct3D 9, который соответствует тому же шаблону и формату данных, что и SetDeviceGammaRamp. Значение по умолчанию для гамма-пандуса Direct3D 9 не особенно полезно; это набор WORD, инициализированный 0-255, а не 0-65535, хотя API определен в терминах 0–65535.

Последний API — IDXGIOutput::SetGammaControl. Этот API имеет более гибкую схему для выражения гамма-управления, как и для расширенного набора форматов отображения DXGI, включая десять целых чисел бит на канал, 16-разрядные форматы с плавающей запятой и формат XR_BIAS расширенный диапазон.

Все эти API работают на одном оборудовании и изменяют одни и те же значения. API Direct3D 9 и DXGI доступны только для записи. Невозможно прочитать значение оборудования, изменить его, а затем задать. Вы можете установить только пандус. Кроме того, задать гамма можно только в полноэкранном режиме приложения. Это ограничение — еще один способ гарантировать, что рабочий стол всегда доступен для чтения. То есть приложение может нарушить свой собственный дисплей, но Windows восстановит предыдущую гамма-рампу, когда приложение теряет полноэкранный режим (например, с помощью alt-tab или ctrl-alt-del).

Эволюция оборудования дисплея

Некоторые новые мониторы могут отображать широкий диапазон интенсивности. Но если формат отображения может представлять только значения от нуля до единицы, отображение должно сопоставлять ноль с самым темным значением, а одно — с самым ярким значением. Это самое яркое значение может быть слишком ярким для удобного просмотра веб-страниц с черным текстом на белом фоне, но отлично подходит для слишком ярких специальных эффектов, таких как просмотр солнечного света, сверкающего из озера или молнии разветвления неба. Таким образом, нам нужен способ выразить эти более широкие диапазоны. DXGI 1.1 и более поздних версий содержит значения формата отображения, которые позволяют 1.0 представлять удобное белое значение и резервирует более широкие значения формата отображения для слишком ярких специальных эффектов. DXGI 1.1 поддерживает два формата отображения, которые могут выражать эти более широкие значения: DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM и 16-битовую плавающую запятую. Полное описание этих форматов см. в разделе Сведения о расширенном формате. Далее мы рассмотрим, почему гамма-API IDXGIOutput::SetGammaControl dxGI требует значений пикселей больше 1,0.

Возможности гамма-управления в DXGI

DXGI позволяет драйверу дисплея выразить свои гамма-элементы управления в виде пошаговой линейной функции. Эта пошаговая линейная функция определяется контрольными точками этой функции, диапазоном значений, в которые функция может преобразовывать, и дополнительной дополнительной операцией масштабирования и смещения, которая может быть применена после преобразования. Приложение может вызвать метод IDXGIOutput::GetGammaControlCapabilities , чтобы получить все эти возможности управления в структуре DXGI_GAMMA_CONTROL_CAPABILITIES .

На этом графике показана линейная функция с четырьмя контрольными точками.

Линейная функция гамма-коррекции

DXGI определяет контрольные точки по их расположению вдоль цветовой оси поверхности. На предыдущем графике расположения контрольных точек : 0, 0,5, 0,75 и 1,0. Эти контрольные точки указывают, что оборудование может преобразовывать значения в диапазоне от 0 до 1,0. DXGI перечисляет эти контрольные точки в элементе массива ControlPointPositionsDXGI_GAMMA_CONTROL_CAPABILITIES и всегда объявляет их в порядке увеличения. DXGI заполняет только первые элементы массива ControlPointPositions и указывает количество элементов с элементом NumGammaControlPointsDXGI_GAMMA_CONTROL_CAPABILITIES. Если значение NumGammaControlPoints меньше 1025, DXGI оставляет остальные элементы ControlPointPositions неопределенными.

Оборудование, представленное этим графом, может преобразовывать значения в диапазон от 0 до 1,25. Таким образом, DXGI устанавливает для членов MinConvertedValue и MaxConvertedValue значения 0,0f и 1,25f соответственно.

DXGI задает элемент ScaleAndOffsetSupportedDXGI_GAMMA_CONTROL_CAPABILITIES , чтобы указать, поддерживает ли оборудование возможность масштабирования и смещения. Если оборудование поддерживает масштабирование и смещение, оно сохраняет простую таблицу подстановки "один к одному", но затем корректирует выходные данные таблицы, чтобы растянуть выходные данные в диапазон больше [0,1]. Оборудование сначала масштабирует значения, поступающие из таблицы подстановки, а затем смещает их.

Примечание

Разные мониторы, подключенные к одному компьютеру, могут иметь разные возможности гамма-управления. Кроме того, возможности гамма-управления на самом деле могут меняться в зависимости от режима отображения выходных данных. Следовательно, мы рекомендуем всегда вызывать IDXGIOutput::GetGammaControlCapabilities для запроса возможностей управления гамма после того, как приложение перейдет в полноэкранный режим.

 

Эти значения возможностей гамма-управления можно использовать для получения значений элементов управления, которые затем можно задать с помощью API IDXGIOutput::SetGammaControl .

Настройка гамма-управления с помощью DXGI

Чтобы задать гамма-элементы управления, необходимо передать указатель на структуру DXGI_GAMMA_CONTROL при вызове API IDXGIOutput::SetGammaControl .

Элементы Масштаб и Смещениезадаются DXGI_GAMMA_CONTROL , чтобы указать значения масштаба и смещения, которые оборудование будет применять к значениям, полученным из таблицы подстановки. Вы можете безопасно задать для параметра Масштаб значение 1, а для смещения — ноль (то есть масштабирование на единицу не оказывает влияния, а смещение нуля не оказывает влияния), если вы не хотите использовать возможность масштабирования и смещения или оборудование не имеет такой возможности.

Для элемента массива GammaCurveDXGI_GAMMA_CONTROL задается список DXGI_RGB структур для точек на гамма-кривой. Каждый элемент DXGI_RGB задает значения float, представляющие красный, зеленый и синий компоненты для этой точки. Гамма-кривая не использует альфа-значения. Для заполнения этого числа элементов в массиве GammaCurve используется число, полученное из NumGammaControlPointsDXGI_GAMMA_CONTROL_CAPABILITIES. Каждый элемент, который помещается в массив GammaCurve , является высотой каждой контрольной точки.

Обратите внимание, что на предыдущем графике теперь у вас есть контроль над вертикальным размещением каждой контрольной точки и у вас есть отдельный элемент управления для красного, зеленого и синего. Например, можно задать для всех зеленых и синих значений нулевое значение, а для красных — по возрастающей лестнице от нуля до единицы. В этом сценарии на изображении отображаются только красные части, а синий и зеленый — черные. Вы также можете задать нисходяющую лестницу для всех цветов, что приводит к инвертированию дисплея. Любое значение, размещенное в массиве GammaCurve , должно быть включаемо в значения, полученные из элементов MinConvertedValue и MaxConvertedValueDXGI_GAMMA_CONTROL_CAPABILITIES.

Практические особенности гамма-контроля

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

Не все адаптеры поддерживают гамма-управление. Если адаптер не поддерживает гамма-управление, он игнорирует вызовы для установки гамма-рампы.

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

Курсор мыши, если он реализован на оборудовании (как и большинство), обычно не реагирует на гамма-параметр.

Руководство по программированию для DXGI