0

OpenGL ES 3.0 を使用して、GPU で流体力学効果を作成しています。16 ビット浮動小数点 FBO を使用すると、効果を正しく機能させることができます。

私の問題は、浮動小数点テクスチャをサポートしていない GPU をターゲットにしていることです。効果は、精度の欠如の下で崩壊します。

この効果は 2 次元にすぎないため、FBO の最初の 2 チャネルのみを読み書きしています。したがって、unsigned int テクスチャの 2 つのチャネルを使用して精度を高めることに成功した人がいるかどうか、またそれがどのように可能であるかを知りたいと思っています。

私の現在の解決策は次のとおりです(GLSLフラグメントシェーダースニペット)、まったくうまくいきません:

#define read(vec) ((((vec).xy * 255.0) - 127.0) / 127.0) + (vec).zw / 255.0

vec4 write(vec2 vec)
{
    vec2 temp = ((vec * 127.0) + 127.0);
    vec2 a = floor(temp) / 255.0;
    vec2 b = mod(temp, 255.0);
    return vec4(a,b);
}

主な問題は、このようなスキームではゼロを書き込むことができないことだと思います。

誰かがこれをすでに解決しているか、そのような問題の解決策を見ることができることを願っています:)

4

1 に答える 1

0

保存したい値は 0.0 から 1.0 の間だと思いますが、有効な 2 バイトのデータを利用して精度を上げたいと思いませんか?

float read(vec2 rawData) 
{
    return rawData.x + rawData.y / 256.0;
}

vec2 write(float value)
{
    return vec2(value, floor(value * 256.0));
}

入力/出力浮動小数点数の制限を [0,1] 以外に設定するには、出力値を範囲 [0,1] にマッピングして write を呼び出すか、入力値を [0,1] から [ にマッピングする必要があります。最小、最大] これは簡単です:

// maps val from [fromMin,fromMax] to [toMin,toMax]
float lerp(float val, float fromMin, float fromMax, float toMin, float toMax)
{
    return toMin + (toMax - toMin) * (val - fromMin) / (fromMax - fromMin);
}

const vec2 minMax = vec2(-5.0, 10.0);

float readMapped(vec2 rawData)
{
    return lerp(read(rawData), 0.0, 1.0, minMax.x, minMax.y);
}

vec2 writeMapped(float value)
{
    return write(lerp(value, minMax.x, minMax.y, 0.0, 1.0));
}

2 チャネルの入出力の場合は、これらの関数を 2 回呼び出すだけです。

于 2013-10-30T10:45:29.783 に答える