我正在编写着色器(HLSL),我需要将颜色值打包成R32格式。我发现了将浮动数据包装成R8G8B8A8格式的各种代码,但它们似乎都没有反过来。我的目标是SM3.0,因此(afaik)位操作不是一种选择。
总结一下,我需要能够做到这一点:
float4 color = ...; // Where color ranges from 0 -> 1
float packedValue = pack(color);
任何人都知道怎么做?
更新
我已经取得了一些的进展......也许这有助于澄清这个问题
我的临时解决方案是这样的:
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;
}
我基本上......假装我使用的是整数类型:s
通过猜测和检查,64是我可以使用的最高数字,同时仍保持[0 ... 1]范围。不幸的是,这也意味着我正在失去一些精确度--6位而不是8位。
答案 0 :(得分:1)
看看: http://diaryofagraphicsprogrammer.blogspot.com/2009/10/bitmasks-packing-data-into-fp-render.html
简短的回答是,不可能将4个浮子无损包装成1个浮子。
即使您确实找到了一种方法来打包4个浮点数,存储它们的指数和有效数字,包装和拆包过程可能会非常昂贵。
答案 1 :(得分:1)
请将3个组件的示例代码打包到s =有效数字中,然后执行exp2(color.g)(1 + s)将其他组件打包到指数中。你仍然会失去精确度,但它不会像你试图将所有内容打包到有效数据中一样糟糕。
不幸的是,没有办法避免失去精度,因为有一堆NaN和Inf浮点值彼此难以区分并且难以使用(甚至可能甚至不受GPU支持,具体取决于它的年龄)是)。