ティムが正しく述べているように、これはアプリケーションによって異なります。いくつかの数値について話しましょう。IBOと、すべてのフレームのテクスチャ座標を1つのVBOに挿入することの両方について言及しているので、それぞれの影響を見てみましょう。
典型的な頂点が次のようになっているとします。
struct vertex
{
float x,y,z; //position
float tx,ty; //Texture coordinates
}
zコンポーネントを追加しましたが、それを使用しない場合、またはより多くの属性がある場合、計算は同様です。したがって、この属性が20バイトかかることは明らかです。
単純なスプライト、つまり2つの三角形で構成される四角形を想定します。非常に単純なモードでは、2x3の頂点を送信6*20=120
し、GPUにバイトを送信するだけです。
インデックス作成では、実際には4つの頂点しかありません1,2,3,4
。2つの三角形1,2,3
と2,3,4
。したがって、2つのバッファをGPUに送信します。1つは4つの頂点(4*20=80
バイト)を含み、もう1つは三角形のインデックスのリスト([1,2,3,2,3,4]
)を含みます。これを2バイトで実行できるとしましょう(65535のインデックスで十分です)。6*2=12
バイトに。合計バイトで、バイトまたは約92
を節約しました。また、GPUをレンダリングすると、頂点シェーダーで各頂点が1回だけ処理される可能性が高いため、処理能力もある程度節約できます。28
23%
したがって、すべてのアニメーションのすべてのテクスチャ座標を一度に追加する必要があります。最初に注意しなければならないのは、インデックス付きレンダリングの頂点はすべての属性によって定義されるため、位置のインデックスとテクスチャ座標のインデックスに分割することはできないということです。したがって、テクスチャ座標を追加する場合は、位置を繰り返す必要があります。80
したがって、追加する各「フレーム」は、VBOにバイトを追加12
し、IBOにバイトを追加します。64フレームあるとすると、最終的に64*(80+12)=5888
バイトになります。1000個のスプライトがあるとすると、これは約になり6MB
ます。これはそれほど悪くはないように見えますが、非常に高速にスケーリングされることに注意してください。各フレームはサイズだけでなく、各属性も追加します(繰り返す必要があるため)。
それで、それはあなたに何をもたらしますか?
- データをGPUに動的に送信する必要はありません。VBO全体を更新するには、
80
バイトまたは640
ビットを送信する必要があることに注意してください。1000
フレームあたりのスプライトに対して30
1秒あたりのフレーム数でこれを行う必要があるとすると、 19200000
bpsまたは19.2Mbps
(オーバーヘッドは含まれません)になります。これは非常に低いですが(たとえば、16xPCI-e32Gbps
で処理できます)、他の帯域幅の問題がある場合(たとえば、テクスチャリングが原因)は、検討する価値があります。また、VBOを慎重に構築する場合(たとえば、個別のVBOまたは非インターリーブ)、テクスチャ部分のみを更新するように減らすことができます16
。これは、上記の例ではスプライトごとに1バイトのみであり、帯域幅をさらに減らす可能性があります。
- 次のフレーム位置の計算に時間を無駄にする必要はありません。ただし、これは通常、テクスチャのエッジを処理するためのいくつかの追加と少数の追加です。ここで多くのCPUパワーが得られるとは思えません。
最後に、アニメーション画像を多くのテクスチャに単純に分割することもできます。これがどのようにスケーリングするかはまったくわかりませんが、この場合、より複雑な頂点属性を操作する必要はなく、アニメーションのフレームごとに別のテクスチャをアクティブにするだけです。
編集:別の方法は、サンプリングの前に、フレーム番号をユニフォームで渡し、フラグメントシェーダーで計算を行うことです。単一の整数ユニフォームを設定することは、それだけのオーバーヘッドになるはずです。