【问题标题】:Adjust brightness/contrast/gamma of scene in DirectX?在 DirectX 中调整场景的亮度/对比度/伽玛?
【发布时间】:2009-08-27 01:22:29
【问题描述】:

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

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

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

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

【问题讨论】:

  • 这不会解决你的问题,但我认为在图像处理上下文中使用 gamma 一词的每个人都应该阅读:alvyray.com/Memos/9_gamma.pdf

标签: directx direct3d


【解决方案1】:

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

SRCBLEND = ONE
DESTBLEND = ONE

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

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

SRCBLEND = DESTCOLOR
DESTBLEND = ZERO

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

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

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

【讨论】:

  • 这听起来很有希望——我将在早上进行实验,看看它在实践中是如何工作的。谢谢!
  • 好吧,其实我已经检查过了,非常完美!显然它不像你说的那样 100% 准确,但它对旧 GPU 友好,总体上非常高效,并且给出的结果足够好。再次感谢!
【解决方案2】:

对于我用 XNA 制作的游戏,我使用了像素着色器。这是代码。 [免责声明] 我不完全确定逻辑是否正确,某些设置可能会产生奇怪的效果(!)[/免责声明]

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(); }
}

【讨论】:

  • 您能解释一下如何动态设置偏移量吗?还是每次更改后都要重新编译着色器代码?
【解决方案3】:

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

【讨论】:

  • 不幸的是,只能在全屏独占模式下工作。也许这对于没有像素着色器的非全屏应用程序是不可能的,我不知道。
  • 文档暗示它可以在窗口模式下工作。在实践中,我预计这将取决于您的显卡和驱动程序。
  • 不幸的是:“在设置新的渐变级别时,请记住,您在数组中设置的级别仅在您的应用程序处于全屏独占模式时使用。” (来自链接)
  • 奇怪。它还说,“因为 gamma 斜坡是交换链的属性,所以可以在交换链窗口化时应用 gamma 斜坡。”我想这意味着它可以应用,但它不会做任何事情。这不是那么有用。 :)
【解决方案4】:

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

【讨论】:

    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

      【讨论】:

      • 感谢您的链接——不过,我不使用视频,所以很遗憾,它是一个完全不同的 API。
      • 我想说的是 DirectX9。
      猜你喜欢
      • 2013-03-02
      • 1970-01-01
      • 2017-08-06
      • 2018-01-29
      • 1970-01-01
      • 2017-08-22
      • 1970-01-01
      • 2011-03-26
      • 2017-08-04
      相关资源
      最近更新 更多