更新:
非常感谢你的回答。正如Jesse Hall所说,它看起来像是一个驱动程序(或硬件)问题。我在其他配置上尝试了相同的应用程序,它按预期工作。
我在其他共享相同GPU(ATI 4800 HD)但不同版本的驱动程序的计算机上测试了应用程序,它们都表现出相同的错误行为(写入时似乎是双伽马校正)。在这些计算机上,如果必须将D3DRS_SRGBWRITEENABLE设置为false以修复显示。任何人都知道这是否是这个硬件上的已知错误?
更奇怪的是,我使用这两种配置得到了相同的最终结果:
在像素调试器中,我看到在情况1中正确应用了线性化,但写入时的(自动)校正给出了与情况2相同的输出(根本不执行转换)...
// - END OF UPDATE
我在修复DirectX9应用程序的伽马校正方面遇到了一些麻烦。
当我在采样器(D3DSAMP_SRGBTEXTURE)和sRGB写入输出(D3DRS_SRGBWRITEENABLE)中启用纹理线性化时,看起来像伽马校正应用了两次。
这是我的设置。我使用以下纹理(来自here)绘制全屏四边形:
图片右侧的结果在视觉上太亮了。我使用PIX调试其中一个灰色像素,如果一切设置正确,我预计输出值为0.73(= 0.5 ^(1.0 / 2.2))。不幸的是,像素着色器的输出是0.871(看起来它可能是应用两次的伽马校正?)。我使用调试器进入像素着色器,纹理提取返回值(0.491,0.491,0.491),这意味着读取时线性化工作正常。
当我禁用D3DRS_SRGBWRITEENABLE时,像素着色器的输出为0.729,这看起来更正确。
知道这种转换来自何处(在调试器中像素着色器输出为0.491)?我应该检查哪些其他标志/渲染状态?
非常感谢你的帮助!
答案 0 :(得分:3)
一种可能性是您将线性伽马变换应用两次。一次用D3DRS_SRGBWRITEENABLE写入渲染目标时。然后在使用D3DPRESENT_LINEAR_CONTENT(如果已指定该标志)呈现帧缓冲区时的其他时间。您不需要D3DPRESENT_LINEAR_CONTENT,因为您已经使用D3DRS_SRGBWRITEENABLE转换回rgb空间。
另一种可能性是您的图形硬件在转换为像素着色器的线性空间之前过滤纹理。您可以通过禁用D3DSAMP_SRGBTEXTURE并过滤,然后在像素着色器中进行线性空间转换和过滤来测试。或者只是将纹理绘制得足够大,以至于过滤不是问题。关于伽玛校正的一篇很好的文章也提到GeForce 8及其后的卡在过滤之前正确转换为线性空间可以在这里找到:
http://http.developer.nvidia.com/GPUGems3/gpugems3_ch24.html
如果您没有使用D3DPRESENT_LINEAR_CONTENT,那么我的下一个猜测是您的显卡不支持您正在进行的伽玛转换。以编程方式或使用DirectX Caps Viewer Tool等工具检查设备功能:
http://msdn.microsoft.com/en-us/library/ee417852%28v=vs.85%29.aspx
答案 1 :(得分:2)
这与问题有关但不完全相关,但值得了解!
我遇到过Vista / Win7上D3D9运行时的错误。此运行时是在D3D10之上编写的各种仿真层。在D3D10中,SRGB状态是纹理格式的属性,在D3D9中它是基于采样器的renderstate。设置D3D9纹理时,SRGB状态始终设置为“off”,因为可能正在使用纹理格式,而D3D9没有SRGB纹理格式。这意味着在绑定纹理后需要设置D3DSAMP_SRGBTEXTURE状态才能正确显示。