【问题标题】:Why does D3DCOLORtoUBYTE4 multiplies components by 255.001953f?为什么 D3DCOLORtoUBYTE4 将分量乘以 255.001953f?
【发布时间】:2018-08-30 18:57:32
【问题描述】:

我编译了一个使用 D3DCOLORtoUBYTE4 内在函数的像素着色器,然后反编译。 这是我发现的:

r0.xyzw = float4(255.001953,255.001953,255.001953,255.001953) * r0.zyxw;
o0.xyzw = (int4)r0.xyzw;

rgba->bgra swizzle 是预期的,但为什么它使用 255.001953 而不是 255.0? Data Conversion Rules 非常具体地说明了应该发生的事情,它说如下:

从浮点数比例转换为整数比例:c = c * (2^n-1)。

【问题讨论】:

  • 通常在进行从浮点颜色到 8 位颜色的转换时,您希望稍微偏向它,以便在您有 1.0 时最终得到 255,即使四舍五入。否则你可能会得到 254,这有时是 Alpha 通道的问题。还值得记住的是,Shader Model 2.0 硬件在像素着色器中通常只有 12 位精度。
  • 简短的回答是:这只是内在定义的一部分。它在所有现代版本的 FXC 中都以这种方式实现。
  • 对我上面的评论的小修正:Shader Model 2.0 Pixel Shaders 需要 fp24 精度。 Shader Model 3.0 或更高版本需要 fp32 精度。
  • 内置舍入,由于截断而需要。 0.001953 * 256 = 0.5

标签: windows direct3d hlsl direct3d11


【解决方案1】:

简短的回答是:这只是内在定义的一部分。它在所有现代版本的 HLSL 编译器中都以这种方式实现。

255.0 作为 32 位浮点数以二进制表示为

0100`0011`0111`1111`0000`0000`0000`0000

255.001953 作为 32 位浮点数实际上表示为 255.001953125,二进制是:

0100`0011`0111`1111`0000`0000`1000`0000

这种轻微的偏差在特定情况下会有所帮助,例如输入值为 0.999999。如果我们使用 255.0,您将得到 254。使用 255.001953,您将得到 255。否则,在大多数其他情况下,转换为整数(使用截断)后的答案会得到相同的答案。

关于浮点数的一些有用和有趣的思考here

【讨论】:

    猜你喜欢
    • 2022-11-26
    • 2019-12-23
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 2021-03-28
    • 2017-06-24
    • 1970-01-01
    • 2022-01-09
    相关资源
    最近更新 更多