8

私は現在、より多くのアニメーションモデルを便利にレンダリングできるフレームワークを開発しています。

モデルは、骨の単純な階層として編成され、ルートは胴体/骨盤です。通常、次のようになります。

私の単純なモデリング階層

したがって、擬似コードとして、私は現在、次のようなモデルをレンダリングしています。

RenderBone(Bone b, Mat4x4 currentTransform){
    Mat4x4 pos = currentTransform * b.boneTransform;
    SetUniform("transformation", pos);
    Draw(bone.mesh);
    for each Bone bc in b.children do{
         RenderBone(bc, pos);
    }
}

したがって、n個のボーンを持つモデルを使用する単一のアクターの場合、n個のSetUniform(テクスチャの設定などはカウントされません)とn個の描画呼び出しが必要です。

そのオーバーヘッドを減らし、同じモデルを使用してすべてのアクターを一度にレンダリングしようとして、インスタンス化されたレンダリングに切り替えることを考えました。

ただし、私が見つけたすべての情報とチュートリアルは、立方体、球体、または同様の単​​純なオブジェクトの描画に関するものです。インスタンス化された描画を使用して、各パーツ(ボーン)がシェーダーに異なる変換行列を与える必要があるモデルをレンダリングする方法について、簡単でわかりやすい情報をどこにも見ることができませんでした。

したがって、問題:glVertexAttribDivisorまたはgl_InstanceIDを使用すると、インスタンス関連のマトリックスのみを指定でき、ボーンで実現されたマトリックスは指定できません。では、どうすれば骨の変形を適用できますか?

私が考えることができる唯一の実行可能な解決策は、モデル全体をインスタンス化する代わりに、各ボーンをインスタンス化できることです。したがって、あるボーンタイプ、次に別のボーンタイプのすべてのインスタンスを描画します。しかし、それでも、変換行列を使用してバッファを比較的頻繁に更新する必要があり、それはより多くのハウスキーピングコードです。

それで、これは最良の選択肢ですか?または、より一般的には、それほど複雑ではないレンダリング方法がありますか?または、インスタンス化されたレンダリングは、静的ジオメトリで使用する場合にのみ実際に輝きますか?

4

1 に答える 1

18

インスタンス化は、同じモデルの何千ものコピーを描画する必要がある場合に使用するものです。一般に、ボーンのあるメッシュは、何千もの描画に必要な種類のものではありません。

インスタンス化は最適化であり、常に効果があるとは限りません必要であることがわかっていない限り、わざわざ採用しようとしないでください(プロファイリングを行い、パフォーマンス目標を達成しているかどうかを確認します)。それでも、実際のパフォーマンスの向上がいつであるかについては、非常に扱いにくい場合があります。

時々、それは役に立たないだけです。ただし、一般的な経験則は次のとおりです。

  1. 何千ものインスタンスをレンダリングしない限り、インスタンス化は価値がありません。
  2. インスタンス化は、頂点が多すぎたり少なすぎたりするメッシュでは使用しないでください。100〜1,000程度。

これらは一般的な規則であり、絶対的な法則ではないことを忘れないでください。また、ハードウェアに依存します。

したがって、問題:glVertexAttribDivisorまたはgl_InstanceIDを使用すると、インスタンス関連のマトリックスのみを指定でき、ボーンで実現されたマトリックスは指定できません。では、どうすれば骨の変形を適用できますか?

あなたは、自分が見た例や他の人がしているのを見たという点で、あまりにも多くのことを考えています。プログラマーのように考えてください。

gl_InstanceID「インスタンス関連のマトリックス」ではありません。インデックスです。そのインデックスで何をするかは完全にあなた次第です。これまで見てきたほとんどの例では、このインデックスを使用して、均一なブロックまたはバッファテクスチャに格納されている可能性のある行列の配列を検索しています。このマトリックスは、レンダリングに使用する変換です。各インデックスは、単一インスタンスの変換を表します。

各インスタンスには、複数の行列、複数の変換があります。ただし、各インスタンスには同じ数のボーンがあります(そうでない場合、インスタンス化されたレンダリングにはなりません)。あなたが5つの骨を持っているとしましょう。

繰り返しますが、各インデックスは単一インスタンスの変換です。ケースと標準の違いは、インスタンスごとに必要な情報の量です。通常の場合、1つの行列が必要です。5つ必要です。しかし、考え方はどちらの方法でも同じです。

現在のインスタンスにボーンインデックス3が必要な場合は、次の式を使用してマトリックス配列にアクセスするだけです。(gl_InstanceID * 5) + 3ここで、5はインスタンスあたりのボーンの数です。

残りは、頂点ごとの属性を使用して、各頂点の変換に使用されるボーンインデックスを渡すという単純な問題です。

于 2012-08-15T16:45:48.517 に答える