我正在写一个着色器(HLSL),我需要将颜色值打包成R32格式.我发现了将浮动数据包装成R8G8B8A8格式的各种代码,但它们似乎都没有反过来.我的目标是SM3.0,因此(afaik)位操作不是一种选择.
总结一下,我需要能够做到这一点:
float4 color = ...; // Where color ranges from 0 -> 1
float packedValue = pack(color);
Run Code Online (Sandbox Code Playgroud)
有人知道怎么做吗?
更新
我已经取得了一些进展......也许这将有助于澄清这个问题.
我的临时解决方案是这样的:
const int PRECISION = 64;
float4 unpack(float value)
{
float4 color;
color.a = value % PRECISION;
value = floor(value / PRECISION);
color.b = value % PRECISION;
value = floor(value / PRECISION);
color.g = value % PRECISION;
value = floor(value / PRECISION);
color.r = value;
return color / (PRECISION - 1);
}
float pack(float4 color)
{
int4 …Run Code Online (Sandbox Code Playgroud) 我读过几个讨论在一个浮点数中存储 2 或 3 个浮点数的链接。这是一个例子:
另一个:
还有另一个:
在 glsl 中将 RGB 值解码为单个浮点数,无需进行位移位
我见过其他人,但他们都使用相同的原理。如果要对 x 和 y 进行编码,它们会将 y 乘以某个因子,然后将 x 添加到其中。嗯,这在纸上是这样的,但我不明白当存储为浮点值时它实际上是如何工作的。浮点值只有 7 位有效数字。如果将一个大数和一个小数相加,小数就会被截断并丢失。精度只显示大数的值。
由于每个人似乎都开出相同的方法,我自己尝试了一下,它的效果正是我想象的那样。当我解码这些数字时,未相乘的数字结果为 0.0。它完全丢失在编码的浮动中。
这是我尝试测试的一些 MaxScript 的示例:
cp = 256.0 * 256.0
scaleFac = 16777215
for i = 1 to 20 do (
for j = 1 to 20 do (
x = (i as float / 20.01f) as float;
y = (j as float / 20.01f) as float;
xScaled = x * scaleFac;
yScaled = y …Run Code Online (Sandbox Code Playgroud)