为什么 D3DCOLORtoUBYTE4 将分量乘以 255.001953f?

Why does D3DCOLORtoUBYTE4 multiplies components by 255.001953f?

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

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 对应该发生的事情非常具体,它说如下:

Convert from float scale to integer scale: c = c * (2^n-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。否则在大多数其他情况下,转换为整数(使用截断)后的答案无论哪种方式都会产生相同的答案。

Some useful and interesting musings on floating-point numbers here