1

在一个充满来自 D3DX 的 Sprite 对象的 Direct3D 应用程序中,我希望能够全局调整亮度和对比度。如果可能的话,对比很重要。

我在这里看到了这个关于 OpenGL 的问题: Tweak the brightness/gamma of the whole scene in OpenGL

但这并没有给我在 DirectX 上下文中需要的东西。我知道这也是我可以用像素着色器做的事情,但这似乎就像用火箭筒射击苍蝇一样,我担心与旧 GPU 的向后兼容性,这些 GPU 必须在软件中执行任何着色器。看起来这应该是可能的,我记得在着色器时代之前,甚至像原来的半条命这样的更老的游戏也有这样的设置。

编辑:另外,请注意,这不是一个全屏应用程序,所以这需要只是影响一个 Direct3D 设备,而不是整体显示器的全局设置。

4

6 回答 6

5

许多游戏确实通过在屏幕上应用全屏多边形和加法混合来增加亮度。IE

SRCBLEND = ONE
DESTBLEND = ONE

然后应用颜色为 (1, 1, 1, 1) 的纹理将使每个像素的亮度(ish)增加 1。

要调整对比度,您需要做类似但乘以一个常数因子。这将需要如下混合设置

SRCBLEND = DESTCOLOR
DESTBLEND = ZERO

这样,如果您将像素与 (2, 2, 2, 2) 值混合,那么您将更改对比度。

Gamma 是一种复杂得多的野兽,我不知道有一种方法可以像上面那样伪造它。

这些解决方案都不是完全准确的,但它们会给你一个看起来“稍微”正确的结果。正确地做任何一种方式都要复杂得多,但是通过使用这些方法,您会看到看起来与您玩过的各种游戏非常相似的效果,那是因为这正是他们正在做的事情;)

于 2009-08-27T21:05:32.647 回答
2

对于我在 XNA 中制作的游戏,我使用了像素着色器。这是代码。[免责声明]我不完全确定逻辑是否正确,并且某些设置可能会产生奇怪的效果(!)[/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(); }
}
于 2009-08-28T02:15:23.233 回答
1

另一种方法是编辑所有纹理。它基本上与伽马贴图的方法相同,只是您将渐变手动应用于每个图像文件中的像素数据以生成纹理。

于 2009-08-27T22:12:00.640 回答
1

只需使用着色器。在这一点上,任何至少不支持 SM 2.0 的东西都是古老的。

于 2009-08-27T22:13:25.973 回答
1

您没有指定您使用的是哪个版本的 DirectX,所以我假设为 9。可能您能做的最好的事情就是使用gamma-ramp 功能。上下推动斜坡增加或减少亮度。增加或减少梯度会改变对比度。

于 2009-08-27T09:03:08.733 回答
0

这个论坛中的答案可能会有所帮助,因为我从未尝试过。

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

于 2009-08-27T01:30:25.160 回答