2

(どのように)GLSLで変換せずにスカラーを別のスカラーにキャストできますか?

この質問で使用される「キャスト」の定義は、2つのタイプが同じビット数であると仮定して、データ自体を変更せずにまったく同じデータの解釈を変更することです。すなわち(フロート)B00101111 == B00101111

この質問で使用される「変換」の定義は、データの解釈と、データを元の値の数学的な近似値、つまり(float)1==1.0に再フォーマットすることの両方を変更することです。

GLSL 4.30.6仕様の5.4.3は、スカラーfloat-to-intおよびint-to-floatコンストラクターが変換のみを実行することを意味します 。浮動小数点値は削除されます。」-pg。87

棺桶のもう一つの釘は、セクション5.1、ページのこの行にあります。85: 「型キャスト演算子はありません。代わりにコンストラクターが使用されます。」

目標は、Buffer-Texture / Texture-BufferとtexelFetch(...)を使用してfloat vec4s(128ビット)を取得し、次のような構造体を埋めることです。

struct MyStruct
{
int foo; //32bit
float bar; //32bit
int baz; //32bit
short blah; //16bit
short hmm; //16bit
} // 128bit total

...しかし、そのvec4をバイナリサブチャンクに分解し、それらを再キャストして上記の構造体値を設定する方法を特定するのに問題があります。

理論的には、次のように機能しますか?

MyStruct myUuberChunk = MyStruct(myVec4);

float vec4s(またはint vec4s)を使用する理由は、それが正しい限り、帯域幅のパフォーマンスを目的として1つの128ビットフェッチですべての値を取得することです(ほとんどのカードには4つの32ビットメモリバスがあります)。

4

2 に答える 2

6

理論的には、次のように機能しますか?

いいえ。

GLSLでは、構造を直接再解釈することはできません。GLSL(3.30+)は、整数と浮動小数点数が32ビットであることを保証しますが、vec4を取得して、それが別のものであると偽ることはできません。

ただし、OpenGL 3.3+では、個々のスカラー値を再解釈できます。まず、コードは浮動小数点テクスチャではなく、整数バッファテクスチャを使用する必要があります。これは、非正規化された値、NaN、またはその他の浮動小数点の奇数の場合に、テクセルフェッチロジックが不快なことをするのを防ぐためです。

したがって、を使用してusamplerBuffer、を取り戻す必要がありますuvec4

実際の値を取得するには、適切なライブラリ関数によって提供されるビットの再解釈を行う必要があります。

struct Data
{
  int first;
  float value;
  int second;
  int half1;
  int half2;
};

Data UnpackStruct(uvec4 packed)
{
  Data ret;
  ret.first = int(packed[0]); //Sign bit is preserved, per GLSL standard.
  ret.value = uintBitsToFloat(packed[1]);
  ret.second = int(packed[2]);
  ret.half1 = (packed[3] >> 16) & 0x0000FFFF;
  ret.half2 = packed[3] & 0x0000FFFF;
  return ret;
}
于 2012-11-28T15:40:57.600 に答える
0

ビット単位の演算を使用して、値、特にビットシフトをデコード/エンコードできます。便利なリンク1、2

于 2012-11-28T14:14:44.913 に答える