私は最新のOpenGL(3.1以降)を使用してレンダラーを作成していますが、今ではユニフォームを処理する効率的で柔軟な方法を作成しようとしています。私は、均一なバッファオブジェクトと、これらを使用するための「一般的な」アプローチとは何かを調べてきました(後者は、残念ながら、期待していたほど多くの結果が得られませんでした)。
OpenGL API呼び出しを減らし、連続したメモリにデータを保存するために、GPUにアップロードする必要がある各データ構造に対して複数の大きなバッファーを作成することを検討しています。各バッファの最大サイズは16kbです(私が理解しているところによると、これはUBOで使用できることが保証されています)。オブジェクトがユニフォームをGPUにアップロードできるようにしたい場合、まだいっぱいではない、アップロード対象のタイプの最初のバッファーをフェッチし、そのバッファー内で次に使用可能なインデックスを取得します。オブジェクトが描画されると、UBOがバインドされ(まだバインドされていない場合)、UBOの要素インデックスがアップロードされます。
これにより、次のような結果になります。
layout(std140) uniform ModelData {
mat4 model_matrix[kNumInstancesPerModelUbo];
}
uniform int u_ModelDataIndex;
layout(std140) uniform SkeletonData {
mat4 bone_transforms[kNumInstancesPerSkeletonUbo][kMaxBones];
}
uniform int u_SkeletonDataIndex;
ただし、次のことも検討しています。
layout(std140) uniform MeshData {
mat4 model_matrix[kNumInstancesPerMeshUbo];
mat4 bone_transforms[kNumInstancesPerMeshUbo][kMaxBones];
}
uniform int u_MeshDataIndex;
いくつかの点で、これは、アップロードされるメッシュに関連するすべてのデータにアクセスするために単一のインデックスを必要とするという点で、はるかにきれいに感じられます。一方、これは手に負えない可能性があります(16kbより大きいバッファーサイズ、無関係なデータ(スケルトンのないメッシュなど)へのハンドル)、またはモデルマトリックスのアップロード中にボーンを言うためのアクセスが許可されていないため、同期の問題も発生します)これがGPUのメモリレイアウトにどのように影響するかはわかりません。
率直に言って、私はここで立ち往生しているように感じ、UBOを高速で柔軟に処理する方法の具体的な例を見つけることができません。
ここで私を助けることができるアドバイスやリソースはありますか?