像素值在 DirectX 11 HLSL 着色器中的表现如何?

穆尔根

在像素着色器中采样纹素值时,采样器始终返回一个 float4。但是,纹理本身可能包含基于 DXGI_FORMAT 的多种格式中的任何一种。任何 _UNORM 格式都可以确保 float4 中的所有值都在 0 和 1 之间,这似乎相当简单。回到 DirectX9 时代,人们几乎假设,无论像素格式如何,所有值采样将始终介于 0 和 1 之间。

DirectX 11 似乎不是这种情况。例如,使用 DXGI_FORMAT_R32_FLOAT 格式的纹理似乎能够存储任何有效的 32 位浮点数,这从一般的角度来看确实有意义,因为您可能没有使用该纹理(或缓冲区)用于渲染。

那么,如果 R32_FLOAT 之类的东西有这样一个任意范围,如果它不使用 0 到 1 范围,渲染管道如何确定输出的像素值呢?它似乎不是 -FLT_MAX 到 +FLT_MAX,因为我可以使用 0.0-65.0 之间的值渲染这种类型的纹理,并且我在最终结果中看到红色。但是调试像素着色器并查看源纹理,只有真正接近 65.0 的值才实际显示为红色。但是,后台缓冲区的最终渲染结果中有很多红色。

这是一个示例源纹理,如 VS 图形调试器中所示:

源 R32_Float 纹理

如果我仅使用像素着色器的基本采样器输出将其渲染到屏幕上,我会得到: 结果图像

后台缓冲区格式为 R10G10B10A10_UNORM。

那么它如何决定浮点纹理的“最大强度”是多少?同样,如果您使用 _SINT 格式之一,它是如何处理的?

比扎鲁斯
  • 如果对纹理进行采样,则返回值不会限制在任何特定范围内。如果纹理格式可以包含 0..1 范围之外的值,Sample/Load 方法将返回这些值不变
  • 当您的像素着色器返回一个值时,该返回值将被限制在您的渲染目标支持的任何范围内。如果您在 R32_FLOAT 上渲染,您的渲染值将不会被限制,并且“有效范围”确实是 -FLT_MAX 到 +FLT_MAX。然后,VS 图形调试器仅根据实际存储在纹理中的最低和最高值在一个范围内显示纹理,因此您可以在调试器中以有意义的方式查看纹理。另一方面,您的后台缓冲区格式使用 UNORM 格式,因此它只能包含 0..1 范围内的值,这意味着每个大于 1 的值都将被限制为 1,这就是为什么这么多你的屏幕是红色的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

TOP 榜单

热门标签

归档