フェースごとの法線のみが必要で、フェースのテックス座標が厳密に0 / 0、0 / 1、1 / 0、1 / 1(またはレイアウトに似ている)である場合、8つの頂点を持つキューブを構築できます。および30(再起動を伴うストリップ)または36(リスト)インデックス。頂点シェーダーでSV_VertexIDに基づく定数配列ルックアップを使用して、法線とテックス座標を取得します。
これを行うと、頂点バッファーにtexcoordや法線を含める必要さえなくなり、さらにメモリを節約できます。
さらに進むと、キューブごとに24頂点まで移動できますが、インスタンス化も使用できます。各キューブは頂点バッファー内の固定サイズ(1x1x1)になり、インスタンスごとのデータとしてスケーリングファクターと位置(キューブが回転しないと仮定すると、マトリックス)があります。回転しない場合、1回限りのコストは24頂点になりますが、各キューブを完全に指定するには6つのフロートが必要です。回転するケースでは16個のフロートを見ていますが、それでもかなりの節約になります(この場合、マトリックス変換でCPU側のボトルネックになる可能性が高くなります。頂点シェーダー-頂点ごとに行われたとしても、非常に高速なので、心配する必要はありません)。
顔ごとのテクスチャの場合、テクスチャ配列を使用します。もちろん、配列内のそのような各テクスチャが同じサイズであることを確認する必要があり、配列自体を変更する必要がある場合は現在のバッチを中断する必要がありますが、そうでなければ問題なく動作します。3番目のtexcoordを頂点定義に追加して、各面に使用する配列スライスを定義します。
これでGSは必要ありません。ジオメトリシェーダーステージを有効にすると、独自のオーバーヘッドが追加されるため、GSを使用するよりも高速に実行する必要があります。
このメソッドを使用して大量のキューブを描画するだけのエンジンでベンチマークコードを実行しました。比較的ローエンドのGPUで60fpsをクリアしながら、プロセスを最適化するために他に何もすることなく、300,000個以上のキューブを簡単に噛むことができます。確かに私はそれらをライティングもテクスチャリングもしていませんが、アルファブレンディングを有効にし、バックフェースカリングを無効にしており、全体的に「最適化のために他に何もしない」部分とバランスが取れているので、この方法で打つことができる球場。