(DirectX9) Гамма-коррекция применяется неявно

ОБНОВИТЬ:

Всем большое спасибо за ваши ответы. Как предположил Джесси Холл, похоже, что это проблема с драйвером (или аппаратным обеспечением). Я пробовал это же приложение на других конфигурациях, и оно работало, как и ожидалось.

Я тестировал приложение на других компьютерах с тем же графическим процессором (ATI 4800 HD), но с разными версиями драйвера, и все они показали одно и то же ошибочное поведение (похоже, это двойная гамма-коррекция при записи). На этих компьютерах необходимо установить для параметра D3DRS_SRGBWRITEENABLE значение false, чтобы исправить отображение. Кто-нибудь знает, является ли это известной ошибкой на этом оборудовании?

Еще более странно то, что я получаю одинаковые конечные результаты с этими двумя конфигурациями:

  • D3DRS_SRGBWRITEENABLE = FALSE и D3DSAMP_SRGBTEXTURE в TRUE
  • D3DRS_SRGBWRITEENABLE = FALSE и D3DSAMP_SRGBTEXTURE в FALSE

В отладчике пикселей я вижу, что линеаризация применяется правильно в случае 1, но (автоматическая) коррекция при записи дает тот же результат, что и в случае 2 (который вообще не выполняет преобразование)...

// -- КОНЕЦ ОБНОВЛЕНИЯ

У меня возникли проблемы с исправлением гамма-коррекции приложения DirectX9.

Когда я включаю линеаризацию текстур в сэмплерах (D3DSAMP_SRGBTEXTURE) и запись sRGB для вывода (D3DRS_SRGBWRITEENABLE), похоже, что гамма-коррекция применяется дважды.

Вот моя установка. Я использовал следующую текстуру (из здесь), чтобы нарисовать полноэкранный четырехугольник: введите здесь описание изображения

Результаты были визуально слишком яркими в правой части изображения. Я использовал PIX для отладки одного из этих серых пикселей, и, если бы все было настроено правильно, я бы ожидал выходного значения 0,73 (= 0,5 ^ (1,0/2,2)). К сожалению, результат пиксельного шейдера был равен 0,871 (похоже, это может быть гамма-коррекция, примененная дважды?). Я вошел в пиксельный шейдер с помощью отладчика, и выборка текстуры вернула значение (0,491, 0,491, 0,491), что должно означать, что линеаризация при чтении работает правильно.

введите здесь описание изображения

Когда я отключаю D3DRS_SRGBWRITEENABLE, результат пиксельного шейдера равен 0,729, что мне кажется более правильным.

введите здесь описание изображениявведите здесь описание изображения

Есть идеи, откуда взялось это преобразование (в отладчике вывод пиксельного шейдера был 0,491)? Какие еще флаги/состояния рендеринга я должен проверить?

Большое спасибо за Вашу помощь!


person Ozirus    schedule 28.06.2011    source источник
comment
Похоже на глюк драйвера. Вы проверяли оборудование от другого поставщика? Если у вас есть твердая текстура, прочитайте ее как sRGB, а затем запишите в неизмененном виде как sRGB, вы должны получить исходное значение (за исключением, возможно, одного или двух младших битов из-за потери точности во время преобразований).   -  person Jesse Hall    schedule 30.06.2011
comment
Большое спасибо! Фактически это похоже на проблему с драйвером. Я обновил вопрос, чтобы дать больше отзывов о проблеме, потому что я еще не совсем ее понимаю ;-)   -  person Ozirus    schedule 07.07.2011


Ответы (2)


Одна из возможностей заключается в том, что вы дважды применяете линейное преобразование в гамма. Один раз при записи в цель рендеринга с D3DRS_SRGBWRITEENABLE. Затем в другой раз при представлении буфера кадра с D3DPRESENT_LINEAR_CONTENT (если вы указали этот флаг). Вам не нужен D3DPRESENT_LINEAR_CONTENT, поскольку вы уже преобразовали обратно в пространство RGB с помощью D3DRS_SRGBWRITEENABLE.

Другая возможность заключается в том, что ваше графическое оборудование фильтрует текстуру перед преобразованием в линейное пространство для вашего пиксельного шейдера. Вы можете проверить это, отключив D3DSAMP_SRGBTEXTURE и фильтрацию, затем выполнив преобразование в линейное пространство и фильтрацию в пиксельном шейдере. Или просто нарисовать текстуру достаточно большой, чтобы фильтрация не была проблемой. Хорошую статью о гамма-коррекции, в которой также упоминается, что карты GeForce 8 и более поздние версии корректно конвертируют в линейное пространство перед фильтрацией, можно найти здесь:

Важность линейности

Если вы не используете D3DPRESENT_LINEAR_CONTENT, то мое следующее предположение состоит в том, что ваша видеокарта не поддерживает выполняемые вами преобразования гаммы. Проверьте возможности устройства программно или с помощью такого инструмента, как DirectX Caps Viewer Tool:

Инструмент просмотра прописных букв DirectX

person dschaeffer    schedule 01.07.2011

Это связано с вопросом, но не совсем, но стоит знать!

Я столкнулся с ошибкой в ​​среде выполнения D3D9 на Vista/Win7. Эта среда выполнения представляет собой своего рода уровень эмуляции, написанный поверх D3D10. В D3D10 состояние SRGB является свойством формата текстуры, в D3D9 это состояние рендеринга на основе сэмплера. При настройке текстуры D3D9 состояние SRGB всегда установлено на «выкл.», потерянное, поскольку формат текстуры, вероятно, используется, а D3D9 не имеет формата текстуры SRGB. Это означает, что состояние D3DSAMP_SRGBTEXTURE должно быть установлено после привязки текстуры, чтобы оно отображалось правильно.

person Zoner    schedule 06.07.2011
comment
Интересно знать... У вас есть URL-адрес с дополнительной информацией об этом? - person Ozirus; 08.07.2011
comment
Странно, но правильно, по крайней мере для меня. После того, как я изменил коды для установки состояний сэмплера после привязки текстуры, результат рендеринга правильный. что касается слоя эмуляции, я слышал о нем, но не представлял, что это может быть такой херней. WTH, я все равно перейду на D3D12. - person crazii; 12.10.2016