HLSL - 浮点数的 asuint 似乎 return 错误值
HLSL - asuint of a float seems to return the wrong value
我一直在尝试将 4 个单位(8 位)编码为一个浮点数,以便我可以轻松地将它们与深度值一起存储在纹理中。我的代码不工作,最终我发现问题归结为:
asuint(asfloat(uint(x))) returns 0 在大多数情况下,当它应该 return x.
理论上,这段代码应该 return x(其中 x 是一个整数),因为 x 中的位被转换为浮点数,然后返回到 uint,所以相同的位最终被解释为又是一个单位。但是,我发现这个函数似乎 return x 的唯一情况是 x 的位被解释为非常大的浮点数。我考虑到这可能是显卡驱动问题的可能性,所以我在两台不同的计算机上进行了尝试,两台计算机都遇到了同样的问题。
我测试了此代码的其他几种变体,所有这些似乎都可以正常工作。
asfloat(asuint(float(x))) = x
asuint(asint(uint(x))) = x
asuint(uint(x)) = x
唯一没有按预期工作的情况是本 post 中提到的第一种情况。这是一个错误,还是我做错了什么?此外,此代码 运行 在 Unity 内的片段着色器中。
经过长时间的搜索,我找到了某种答案,所以我想我会 post 在这里,以防其他人偶然发现这个问题。这段代码不起作用的原因与 float 反规范化有关。 (我不完全理解。)无论如何,asuint 将非规范化浮点数解释为 0,因此非规范化浮点数的 asuint 将始终为 0。
一个稍微可以接受的解决方案可能是 (asuint(asfloat(x | 1073741824)) & 3221225471)
这确保了浮点数被规范化,但它也会擦除存储在第二位中的所有数据。如果有人有任何其他解决方案可以保留此位,请告诉我!
我一直在尝试将 4 个单位(8 位)编码为一个浮点数,以便我可以轻松地将它们与深度值一起存储在纹理中。我的代码不工作,最终我发现问题归结为:
asuint(asfloat(uint(x))) returns 0 在大多数情况下,当它应该 return x.
理论上,这段代码应该 return x(其中 x 是一个整数),因为 x 中的位被转换为浮点数,然后返回到 uint,所以相同的位最终被解释为又是一个单位。但是,我发现这个函数似乎 return x 的唯一情况是 x 的位被解释为非常大的浮点数。我考虑到这可能是显卡驱动问题的可能性,所以我在两台不同的计算机上进行了尝试,两台计算机都遇到了同样的问题。
我测试了此代码的其他几种变体,所有这些似乎都可以正常工作。
asfloat(asuint(float(x))) = x
asuint(asint(uint(x))) = x
asuint(uint(x)) = x
唯一没有按预期工作的情况是本 post 中提到的第一种情况。这是一个错误,还是我做错了什么?此外,此代码 运行 在 Unity 内的片段着色器中。
经过长时间的搜索,我找到了某种答案,所以我想我会 post 在这里,以防其他人偶然发现这个问题。这段代码不起作用的原因与 float 反规范化有关。 (我不完全理解。)无论如何,asuint 将非规范化浮点数解释为 0,因此非规范化浮点数的 asuint 将始终为 0。
一个稍微可以接受的解决方案可能是 (asuint(asfloat(x | 1073741824)) & 3221225471) 这确保了浮点数被规范化,但它也会擦除存储在第二位中的所有数据。如果有人有任何其他解决方案可以保留此位,请告诉我!