0

わかりました... 6 つの異なる法線を持つ比較的単純なソリッドがあるとしますが、実際には 48 面 (方向ごとに 8 面) 近くの面があり、面間に多くの共有頂点があるとします。OpenGLでそれをレンダリングする最も効率的な方法は何ですか?

頂点を配列に配置し、インデックス配列を使用してそれらをレンダリングできることはわかっていますが、法線を変更するには、レンダリング手順を分割し続ける必要があります (つまり、法線 1 を設定... 8 つの面をレンダリング... 法線を設定) 2... 8 つの面をレンダリングするなど) そのため、インデックス配列の配列を維持する必要があります...法線ごとに 1 つです! 良くない!

別の法線配列と頂点配列を使用する (またはそれらをインターリーブする) こともできますが、これは、法線と頂点の比率を 1 対 1 にする必要があることを意味し、法線が 8 倍以上複製されることを意味します。必要以上に!球面または曲面のあるものでは、すべての法線が異なる可能性が最も高いですが、これについては、メモリの無駄のように思えます.

完璧な世界では、頂点と法線配列の長さが異なるようにしたいので、三角形または四角形を描画するときに、その頂点の各配列へのインデックスを指定します。

OBJ ファイル形式では、正確にそれを指定できます... 頂点配列と異なる長さの法線配列を指定すると、レンダリングする面を指定するときに、頂点と法線インデックス (および場合は UV 座標) を指定します。あなたもテクスチャを使用しています)これは完璧なソリューションのようです! 48 個の頂点がありますが、法線は 8 個しかありません。次に、シェイプの面を定義するインデックスのペアです。しかし、OpenGL ES でそれをレンダリングする方法がわかりません (繰り返しますが、'ES' に注意してください)。現​​在、法線を 1 対 1 に戻す必要があります頂点配列、次にレンダリングします。記憶を無駄にするだけです。

誰か助けて?ここで非常に単純なものが欠けていることを願っています。

マーク

4

1 に答える 1

1

あなたは何も見逃していません。これがほとんどのハードウェアの動作方法であるため、これが仕様の動作方法です(つまり、パーフェクトはハードウェアパーフェクトではありません)。

インデックスの配列をサポートするハードウェアの実装の複雑さについては説明しませんが、失う可能性のある最適化の1つを指摘します。GLは、単一のインデックスを頂点変換後のキャッシュへのインデックスとして使用する可能性があります。次の反復で頂点を再変換する必要はありません。一連のインデックスを使用して、その最適化を大幅に複雑にします。

メモリの節約について:あなたの場合、4つの四角形、8つの三角形を使用して、各面が大まかに立方体になっています。つまり、9 * 6=54の一意の頂点について話しているのです。位置と法線しかない場合は、54 * 4 * 3 * 2 =1296Bの頂点データ+2* 48 * 3 = 288 Bのインデックスデータ(属性ベースタイプに4バイト、インデックスにGLushortを想定)です。総計1584B。これは、位置と法線についても最適でないデータ形式を想定しています。代替案は、およそ26 * 4 * 3(pos)+ 8 * 4 * 3(norm)+ 2 * 48 * 3 * 2 = 312 + 96 + 576=984Bです。したがって、この不自然なケースで約0.5kB節約できました。これを属性のより多くのメモリ節約タイプに渡すと、次のようになります。648 + 288 = 936 vs 156 + 48 + 576 =780...違いは無視できるようになります。

なぜ私はこれを持ち出すのですか?メモリ消費の最適化が必要な場合は、属性のデータ型を確認する必要があるためです。

最後に、ご存知のように、実際の3Dの世界(つまり、ボックスの世界ではない)では、このようなメカニズムの節約は少なくなります。共有できる属性はごくわずかです。

于 2010-01-09T08:45:38.683 に答える