9

シェーダー (HLSL) を作成していて、色の値を R32 形式にパックする必要があります。float を 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
推測とチェックの結果、[0...1] の範囲を維持しながら使用できる最大数は 64 でした。残念ながら、これは精度がいくらか失われていることも意味します - 8 ビットではなく 6 ビットです。

4

2 に答える 2

1

見てください: http://diaryofagraphicsprogrammer.blogspot.com/2009/10/bitmasks-packing-data-into-fp-render.html

簡単に言えば、4 つの float を 1 つの float にロスレス パッキングすることはできないということです。

4 つの float をパックし、それらの指数と有効桁数を格納する方法を見つけたとしても、パックとアンパックのプロセスは非常に高価になる可能性があります。

于 2011-01-29T19:03:20.567 に答える
1

3 つのコンポーネントのサンプル コードのように、それらを s=significand にパックし、exp2(color.g)(1+s) を実行して他のコンポーネントを指数にパックします。それでも精度は失われますが、やっているように仮数にすべてを詰め込もうとするほど悪くはありません。

残念ながら、精度の低下を避ける方法はありません。NaN と Inf の float 値は互いに区別がつかず、処理が難しい (古いものによっては GPU でサポートされていない可能性もあります) ためです。

于 2011-02-05T10:50:31.823 に答える