在float中打包四个字节

时间:2011-01-26 23:12:32

标签: hlsl packing

我正在编写着色器(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位。

2 个答案:

答案 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支持,具体取决于它的年龄)是)。