2

ネストされた構造体を使用して、GLSL でポリモーフィズムのようなものをシミュレートしようとしています。

struct Primitve{
   Sphere s;
   Plane p;
   Triangle t;
   int type;
};

整数型は、このプリミティブが実際に何であるかを指定します。このようにして、すべてのプリミティブを 1 つの配列に入れることができます。1 つの欠点は、メモリの浪費です。

だから私の質問は、「パックされた」レイアウトタイプについてです。このタイプのシェーダー ストレージ バッファーを作成すると、

layout(packed) buffer PrimitiveBuffer{
   Primitive primitives[];
};

このデータのブロックは、まったく使用されていないメンバーにデータを割り当てないことで最適化されますか? ウィキは、パックされたレイアウトに関して次のように述べています。

私はこれを正しく理解していますか、それともアライメントの制限によりパドリングのみを考慮していますか?

4

2 に答える 2

2

コンパイラは要素を最適化できますか? はい。ますか?未使用であることを静的に判断できる場合のみ。

この関数を考えてみましょう:

void ProcessPrimitive(int index)
{
  if(primitives[index].type == 0)
  {
    primitives[index].s ...
  }
  else if(primitives[index].type == 1)
  {
    primitives[index].p ...
  }
  else
  {
    primitives[index].t ...
  }
}

コンパイラは、特定のインデックスのtypeフィールドがどうなるかをどのように知ることができますか? 特定のインデックスが球などになることをどのように知ることができますか? できません。したがって、何かを最適化することはできません。

スペースを節約したい場合は、データ変換を自分で実装する必要があります。そのため、タイプ フィールドに基づいて Sphere などに変換できる、プリミティブに情報の一般的な「フロート」を格納する必要があります。

于 2013-03-18T02:02:21.880 に答える
1

複数のシェーダープログラム間でバッファーを共有するかどうかによって異なります。

そうでない場合は、パックされたメモリレイアウトを使用して、基本的に実装に次のように伝えることができます。

ただし、この場合、ブロック内のメンバーの場所を明示的に照会する必要があることに注意してください。

ただし、最終的には、「シェーダーの結果に影響を与えない」ものを見つけるのはGLSLの実装次第です。少しプロファイリングする必要があると思います。

于 2013-03-17T19:46:15.530 に答える