DXGI_FORMATs的确切颜色空间是什么?

5
在DXGI_FORMAT的官方文档中,它告诉我们只有带有_SRGB枚举后缀的格式才在sRGB颜色空间中。我认为没有这个后缀的其他格式都在线性空间中。但是我在DirectXTex库的格式转换函数中发现了一个非常奇怪的行为。(您可以从http://directxtex.codeplex.com/下载它。)
首先,我使用NVIDIA Photoshop DDS插件将纹理文件导出为DXGI_FORMAT_R32G32B32A32_FLOAT。然后我使用LoadFromDDSFile()函数加载此文件,并使用Convert()函数将其格式转换为DXGI_FORMAT_R16G16B16A16_UNORM。(这两个函数都由DirectXTex库提供。)
你猜怎么着?在图像被转换为DXGI_FORMAT_R16G16B16A16_UNORM之后,所有像素的亮度也发生了变化,整个图像比以前更亮。
如果我在将图像转换为DXGI_FORMAT_R16G16B16A16_UNORM格式后手动将像素值从sRGB空间转换为线性空间,则得到的像素值与输入相同。因此,我认为DirectXTex库将DXGI_FORMAT_R32G32B32A32_FLOAT视为线性颜色空间中的格式,并将DXGI_FORMAT_R16G16B16A16_UNORM视为sRGB颜色空间中的格式,然后进行了从线性空间到sRGB空间的颜色空间转换。(我试图找出为什么Convert()函数也会转换颜色空间,但它是由WIC实现的,没有源代码。)
那么,DirectXTex库中是否存在任何错误?还是DXGI_FORMAT的真正标准?如果某些特殊的DXGI_FORMAT有不同的颜色空间,请告诉我在哪里可以找到规范。
任何帮助都将不胜感激。谢谢!
1个回答

4
按照惯例,浮点RGB值是线性的,而整数RGB值是伽马压缩的。对于浮点数,伽马压缩没有任何特别的好处,因为使用伽马的原因是在感知需要更多位时使用更多位,而浮点数已经具有足够(甚至过多)数量的位,并且已经使用指数进行了伪对数编码。(source
请注意,DXGI中整数RGB纹理的色彩空间如果不是特定的*_SRGB,则取决于驱动程序,并且通常具有固定的伽马值0.5。
DirectXTex库似乎表现正确。但是,请注意,您还要依赖于用于捕获和显示DDS文件的任何软件的行为。仅测试DirectXTex的更好方法是在库中执行浮点数->整数->浮点数的往返转换,并在数字上比较结果,而不是在视觉上。

谢谢你的回答!它真的帮了我很多。但是我仍然有一个问题:你说整数RGB值通常是伽马压缩的,并且具有_SRGB的DXGI格式具有固定的伽马0.5。那么这两者之间有什么区别?它们的伽马相等吗?或者_SRGB只是意味着它的值需要由硬件转换?谢谢! - SeaStar
你好SeaStar,sRGB具有更复杂的伽马形式,不是一个单独的数字。我说DXGI格式是整数,但没有_SRGB后缀,则具有固定伽马,可能为0.5。具有_SRGB后缀的格式应该是sRGB,因此具有复杂的伽马。更多信息:“与大多数其他RGB颜色空间不同,sRGB伽马无法表示为单个数字值。” http://en.wikipedia.org/wiki/SRGB 希望这可以帮助到你! - Alex I
我在之前的评论中打错了一个字,我想说的是“带有_SRGB的DXGI格式没有固定的0.5伽马值。”今天我做了更多的研究。 - SeaStar
根据DXGI格式的数据转换规则(您可以在此处找到http://msdn.microsoft.com/en-us/library/dd607323%28v=vs.85%29.aspx),只有在SRGB格式和浮点格式之间转换时才执行伽马校正或反向操作。(也许还包括整数格式和SRGB格式之间的转换)它使用了您上面提到的确切sRGB转换公式。因此,DirectXTex库(或者我们应该责怪WIC?)的确表现出奇怪的行为,或者至少没有遵循标准。 - SeaStar
我还通过比较输出值和原始值,计算出了正确的伽马值,该值由DirectXTex库用于将ARGB32F转换为ARGB16UNORM,约为2.2764,而不是通常的2.0或2.2。对我来说,现在我只想使用正确的伽马值将其转换回线性空间并继续我的工作。再次感谢您。对于我的英语不好,我很抱歉。 - SeaStar
它在这里有更详细的描述:http://msdn.microsoft.com/en-us/library/hh972627%28v=vs.85%29.aspx - SeaStar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接