我正在写一个着色器(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 iVal = floor(color * (PRECISION - 1));
float output = 0;
output += iVal.r * PRECISION * PRECISION * PRECISION;
output += iVal.g * PRECISION * PRECISION;
output += iVal.b * PRECISION;
output += iVal.a;
return output;
}
Run Code Online (Sandbox Code Playgroud)
我基本上......假装我正在使用整数类型:s
通过猜测和检查,64是我可以使用的最高数字,同时仍保持[0 ... 1]范围.不幸的是,这也意味着我正在失去一些精确度--6位而不是8位.
看一下: http://diaryofagraphicsprogrammer.blogspot.com/2009/10/bitmasks-packing-data-into-fp-render.html
简而言之,不可能将 4 个浮点无损打包为 1 个浮点。
即使您确实找到了打包 4 个浮点数并存储它们的指数和有效数的方法,打包和解包过程也可能会非常昂贵。