Я рисую растровые изображения в Direct2D. Растровые изображения используют прозрачность (альфа-канал).
Смешивание выглядит неправильно.
В качестве теста я загрузил чистое черное изображение PNG с прозрачностью 50% и нарисовал его на белом фоне. Результатом являются пиксели со значениями красного, зеленого и синего 127 (0x7F7F7F). Это говорит о том, что смесь Direct2D игнорирует гамму и обрабатывает значения цвета, как если бы они были линейными.
(Растровые изображения используют обычное цветовое пространство sRGB и имеют размер 32 бита на пиксель, по 8 бит для красного, зеленого, синего и альфа-канала). Они загружаются в формате GUID_WICPixelFormat32bppPBGRA.
В sRGB смесь на полпути между черным и белым составляет 186 (0xBABABA). Это идеальный результат, который я хочу.
Может ли Direct2D отображать прозрачность с учетом гаммы? Как бы я это сделал? Любая помощь приветствуется.
Смешивание правильно выполняется в линейном цветовом пространстве, поэтому процесс смешивания пикселей sRGB должен быть
Обратите внимание, что с черными или белыми пикселями шаги (1) и (3) не допускаются и могут быть пропущены.
Увидеть обработка альфа-канала раздел спецификации PNG. В частности, обратите внимание на это:
Уравнение для вычисления значения составной выборки
output = alpha * foreground + (1-alpha) * background
где альфа-значение и входные и выходные значения выборки
выражается в виде дроби в диапазоне от 0 до 1. Это вычисление должно быть
выполняется с выборками интенсивности (не с гамма-кодированием)
Раздел содержит пример кода C для обработки альфа-канала.
В то время, когда был задан этот вопрос, цели HWND Render (рисование на экране) не поддерживали линейные пиксельные форматы; однако цели Direct-2D HwndRender теперь заменены интерфейсом ID2D1DeviceContext. Они созданы через IDXGIFactory2::CreateSwapChainForHwnd()
и поддерживает больше форматов пикселей, таких как DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, который автоматически выполняет правильные преобразования цветового пространства при смешивании (информация предоставлена @Jeff McClintock).
Direct-2D 1.0 HwndRenderTarget выполняет расчеты смешивания непосредственно для значений пикселей. Это приводит к ошибкам при компоновке стандартных изображений sRGB с использованием альфа-канала. Ошибка заключается в том, что Direct 2D обрабатывает значения интенсивности со сжатием гамма-излучения как если бы они были линейными значениями интенсивности.
Игнорирование гаммы приводит к низкому качеству компоновки, сглаживанию геометрии, изменению размера изображения и визуализации текста.
Существует обходной путь, который заключается в том, чтобы «предварительно деформировать» альфа-значения растрового изображения, чтобы компенсировать ошибки, вносимые расчетом смешивания.
пример:
Изображение слева — правильное наложение, выполняя смешивание в линейном цветовом пространстве, центральное изображение — Direct 2D (слишком темная и контрастная тень), изображение справа — Direct2D после предварительной деформации альфа-канала.
увидеть: https://bel.fi/alankila/lcd/alpcor.html
ОБНОВЛЕНИЕ !: Новые версии Direct-2D (1.1) Поддерживает обратные буферы SRGB, которые выполняют смешивание правильно. Используйте IDXGIFactory2 :: CreateSwapChainForHwnd (), чтобы использовать улучшенные параметры глубины цвета.