楽しい部分になりました! ここで、私の研究中に見つけたいくつかの解決策を紹介します。 視覚化プロセスの観点からゲームリソースを最適化する方法の一般的なアイデアを提供してくれることを願っています。
1.並べ替え
まず、コマンドバッファーに入力する前に、すべてのコマンドを(たとえば、レンダリング状態で)並べ替えることができます。 この操作は、同じタイプのすべてのポリゴンメッシュを処理できるため、レンダリング状態に必要な変更の数を最小限に抑えます。
ただし、すべてのポリゴンメッシュを1つずつ表示するため、依然としてかなりのオーバーヘッドがあります。 それらを短縮するために、 Batchingと呼ばれる便利なテクニックがあります。
2.バッチ処理
ポリゴンメッシュを並べ替える場合、タイプごとにグループ化して並べ替えます。 次のステップでは、GPUに各ヒープを一度に視覚化するように依頼します。 これがバッチ処理のポイントです。
バッチ処理は、APIメソッドを呼び出してレンダリングする前に、いくつかのポリゴンメッシュをグループ化したものです。 これは、1つの大きなポリゴンメッシュのレンダリングにかかる時間が、多くの小さなポリゴンメッシュの場合よりも短いという事実によるものです。 [ a36 ]したがって、ポリゴンメッシュ(同じレンダリング状態を持つ)で1つの描画呼び出しを呼び出す代わりに ...
...(同じレンダリング状態の)ポリゴンメッシュを組み合わせて、1つのDraw Callで表示します。 これは非常に興味深いトピックです。なぜなら、 異なるレンダリング(石、椅子、剣) を同時に視覚化でき、同時に同じレンダリング状態を使用しているためです(本質的に、これは同じマテリアル設定を使用することを意味します)。
ポリゴンメッシュの結合はランダムアクセスメモリ(RAM)で発生し、新しい大きなグリッドがグラフィックカード(VRAM)のメモリに転送されることを覚えておくことが重要です。 時間がかかります! したがって、バッチ処理は静的オブジェクト(石、家など)に適しています。これらは一度結合され、長期間メモリに保存されます。 もちろん、宇宙ゲームのレーザーショットなどの動的なオブジェクトを組み合わせることができます。 しかし、それらは常に移動しているため、「ショットのクラウド」グリッドを作成し、フレームごとにGPUメモリに転送する必要があります。
注意が必要なもう1つのポイント( リマインダーのkoyimaに感謝します):オブジェクトがカメラの視野に入らない場合、単純に破棄することができます(表示されても無視されます)。 ただし、複数のオブジェクトをグループ化する場合、視覚化中に、ポリゴンメッシュ全体を全体として考慮する必要があります(実際に表示されるのはごく一部だけです)。 場合によっては、これによりパフォーマンスが低下する可能性があります。
動的オブジェクトを処理するためのより適切なソリューションは、 インスタンス化です。
3.インスタンス
インスタンス化するとは、複数ではなく1つのポリゴンメッシュ(たとえば、レーザーショット)のみを送信し、GPUにそれを数回複製させることです。 同じオブジェクトを同じ位置に同じ回転またはアニメーションで描画するのは非常に退屈です。 したがって、変換マトリックスなどの追加データのストリームを転送して、異なる位置(および異なるポーズ)での複製を視覚化できます。
コピーの一般的な属性は、モデルからワールドへの変換マトリックス、コピーの色、およびボーンに沿ったアニメーションプレーヤーです。 [ a37 ]私をbeatしむ必要はありませんが、私が理解しているように、このデータストリームは、GPUがアクセスできるRAM内の単なるリストです。
合計、ポリゴンメッシュタイプごとに1つの描画呼び出しのみが必要です! バッチ処理と比較すると、違いはすべてのインスタンスが同じように見えることです(同じグリッドがコピーされるため)。一方、マージされたグリッドは、同じRender Stateパラメーターを使用する場合、いくつかの異なるもので構成できます。
さらに、すべてが少し変わったものになります。 次のトリックは、特別な機会にのみ適しているとしても、クールだと思います。
4.マルチマテリアル用のシェーダー
シェーダーは複数のテクスチャにアクセスできるため、たとえば、1つの拡散/通常/反射テクスチャだけでなく、2つを使用できます。 当然、これは1つのシェーダーで2つのマテリアルを結合できることを意味します。 材料は一緒に混合され、混合の程度は制御するテクスチャによって決まります。 もちろん、これにはGPUからの追加コストが必要です。ミキシングは高価な操作ですが、ポリゴンメッシュをパーツに「引き裂く」必要がないため、Draw Callの数が減ります( 「4.ポリゴンメッシュとマルチマテリアル」を参照) )
詳細については、こちらをご覧ください。
ドキュメントには、この高価な手法よりも多くのDraw Callが依然として優れていると書かれています。 それにもかかわらず、私にとって非常に興味深いようでした。統計に良い数値が必要な場合、「レイヤー化された」素材はDraw Callの数を減らすと言えます(パフォーマンスについては何も言わないでください...
5.「スキン」ポリゴンメッシュ
上記のレーザーショットグリッドについて述べたことを覚えていますか? ショットは常に移動しているため、このポリゴンメッシュはフレームごとに更新する必要があると言いました。 それらを組み合わせて、フレームごとに結果を送信するのは非常に高価です。 この問題を解決するための興味深いアプローチは、各ショットにボーンを自動的に追加し、情報を「スキン」として送信することです。 したがって、1つの大きなポリゴンメッシュを使用できます。このメッシュはメモリ内に残り、ボーンに関する情報のみを各フレームで更新します。 もちろん、新しいショットオブジェクトが作成されるか、古いショットオブジェクトが破壊される場合、ポリゴンメッシュを再作成する必要があります。 しかし、それは本当に面白いアイデアのように聞こえます、それは私には思えます。
詳細については、こちらをご覧ください。
Draw Callの数を減らすための珍しい解決策についてのリンクをお気軽にお送りください!ほとんどすべて! これで、ゲームリソースを少し速くレンダリングするために何ができるかをある程度理解できました。 心配しないで、次の本は短くなります。
終わり
地獄のレンダリング1.1:
- ブック1:概要
- ブック2:問題
- ブック3:ソリューション
- ブック4:結論
ここで、私たちがすでに研究したことを簡単に説明します。
小さなポリゴンメッシュを避ける
小さなグリッドの必要性を確認するか、複数の小さなグリッドを1つの大きなグリッドに結合することは可能ですか。 グラフィックプログラマーに相談して、ポリゴン数(パフォーマンスの低下を引き起こさない最大の三角形)の「ゴールデンメーン」に関する情報を取得します。 いくつかの三角形を追加して、角を滑らかにすることもできます。 マルチメディアも監視する必要があります。 1つの大きなポリゴンメッシュを組み立てたが、5つのマテリアルが割り当てられている場合、大きなメッシュは視覚化のために分割されます。つまり、5つの小さなグリッドが残っています。 たぶん、テクスチャアトラスがあなたを助けるでしょうか?
材料を使いすぎないようにしてください。
材料といえば、それらを管理することを考えてください。 リソースを作成する前にゲームリソースを計画しておけば、ゲームリソース間でマテリアルを共有できる場合があります。 大きなテクスチャアトラスが役立ちます。
デバッグツール
1つまたは別のゲームリソースの問題を理解するために、ゲーム内の統計を取得できるかどうかをプログラマーと話し合ってください。 複雑なゲームリソースの一般的なアイデアを得ることは難しい場合があります。 ただし、一部のリソースに潜在的なパフォーマンスの問題があることをツールが警告できる場合は、最終的に修正される前に問題を解決できます。
エンコーダーに聞く
ご覧のとおり、このトピックは非常に技術的であり、コンテキスト(ハードウェア、エンジン、ドライバー、ゲームの見通しなど)に大きく依存しています。 したがって、もちろん、ゲームリソースを構成する方法についてプログラマーに相談することをお勧めします。 または、パフォーマンスの低下がリソースによるものである場合、プログラマがあなたを見つけて、あなたがやったすべてを最適化するまであなたを突きます。 :)
ここに追加すべきヒントを知っていますか? 教えてください!うわー、ここまで読んだことがありますか? あなたはクレイジーです! どうもありがとう! あなたがそれについてどう思うか教えてください。 あなた自身のために何か新しいことを学んだことを願っています。 :)
終わり
[a36] 技術的な内訳-アサシンクリードII
[a37] NVidia GPU Gems 2