Отрегулировать яркость / контрастность / гамму сцены в DirectX? - PullRequest
1 голос
/ 27 августа 2009

В приложении Direct3D, заполненном объектами Sprite из D3DX, я хотел бы иметь возможность глобально регулировать яркость и контрастность. Контраст важен, если это вообще возможно.

Я видел этот вопрос здесь об OpenGL: Отрегулируйте яркость / гамму всей сцены в OpenGL

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

РЕДАКТИРОВАТЬ: Кроме того, обратите внимание, что это не полноэкранное приложение, так что это должно быть что-то, что может повлиять только на одно устройство Direct3D, и это не глобальная настройка для монитора в целом.

Ответы [ 6 ]

5 голосов
/ 28 августа 2009

Многие игры увеличивают яркость, буквально применяя полноэкранную поли по экрану с аддитивным смешиванием. т.е.

SRCBLEND = ONE
DESTBLEND = ONE

и затем применение текстуры с цветом (1, 1, 1, 1) увеличит яркость (иш) каждого пикселя на 1.

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

SRCBLEND = DESTCOLOR
DESTBLEND = ZERO

Таким образом, если вы смешаете пиксель со значением (2, 2, 2, 2), вы измените контраст.

Гамма - гораздо более сложный зверь, и я не знаю, как вы можете подделать его, как описано выше.

Ни одно из этих решений не является абсолютно точным, но оно даст вам результат, который выглядит "немного" правильным. Гораздо сложнее делать все правильно, но с помощью этих методов вы увидите эффекты, которые будут НЕВЕРОЯТНО похожи на различные игры, в которые вы играли, и это потому, что это именно то, что они делают;)

2 голосов
/ 28 августа 2009

Для игры, которую я сделал в XNA, я использовал пиксельный шейдер. Вот код [Disclaimer] Я не полностью уверен, что логика верна, и некоторые настройки могут иметь странные эффекты (!) [/ ​​disclaimer]

float offsetBrightness = 0.0f;    //can be set from my C# code, [-1, 1]
float offsetContrast   = 0.0f;    //can be set from my C# code  [-1, 1]

sampler2D screen : register(s0);  //can be set from my C# code

float4 PSBrightnessContrast(float2 inCoord : TEXCOORD0) : COLOR0
{
    return (tex2D(screen, inCoord.xy) + offsetBrightness) * (1.0 + offsetContrast);
}

technique BrightnessContrast
{
    pass Pass1 { PixelShader = compile ps_2_0 PSBrightnessContrast(); }
}
1 голос
/ 28 августа 2009

Просто используйте шейдер. Все, что по крайней мере не поддерживает SM 2.0, на данный момент является древним.

1 голос
/ 28 августа 2009

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

1 голос
/ 27 августа 2009

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

0 голосов
/ 27 августа 2009

Ответы на этом форуме могут быть полезны, так как я никогда не пробовал это.

http://social.msdn.microsoft.com/Forums/en-US/windowsdirectshowdevelopment/thread/95df6912-1e44-471d-877f-5546be0eabf2

...