2

OpenGL ES 3 とは異なり、gl.mapBufferRange andgl.bufferSubDataなし(存在する)、WebGL 2 で均一なバッファ データを更新する効率的な方法は何ですか? たとえば、PerDraw Uniform ブロック

uniform PerDraw
{
    mat4 P;
    mat4 MV;
    mat3 MNormal;
} u_perDraw;
4

1 に答える 1

2

gl.bufferSubDataが存在するため、バッファを作成してから並列 typedArray を作成するように見えます。typedArray を更新し、それを呼び出し gl.bufferSubDataてバッファにコピーし、更新をgl.bindBufferRange行って使用します。

それはおそらくまだ非常に速いです。まず、すべての値操作は JavaScript にとどまるため、WebGL を呼び出すオーバーヘッドが少なくなります。更新するユニフォームが 10 個ある場合、WebGL への呼び出しを 10 回ではなく 2 回行っていることになります。

TWGL.jsでは、すべてのユニフォームの ArrayBufferViews を単一の型指定された配列に生成します。たとえば、上記のユニフォーム ブロックを指定すると、次のことができます。

ubo.MV[12] = tx;
ubo.MV[13] = ty;
ubo.MV[14] = tz;

または別の例として、配列/ typedarray を宛先パラメーターとして受け取る数学ライブラリがある場合、次のようなことができます

var dest = ubo.P;
m4.perspective(fov, aspect, zNear, zFar, dest);

私が抱えている 1 つの問題は、均一な最適化を扱うことです。シェーダーを編集すると、たとえばデバッグ中output = vec4(1,0,0,1); return;で、フラグメント シェーダーの先頭に挿入すると、一部の均一なブロックが最適化されてコードが壊れます。C/C++ プロジェクトでこれを処理する標準的な方法が何であるかはわかりません。C++では、構造体を宣言すると思います

struct PerDraw {
  float P[16];
  float MV[16];
  float MNormal[9];
}

それで、問題の種類はなくなります。twgl.js では、実行時にその構造を効果的に生成しています。つまり、コードが存在することを期待しているが、最適化されているために生成されない場合、コードが壊れます。

twgl で、JavaScript オブジェクトから型指定された配列にコピーする関数を作成したので、残念ながらオーバーヘッドが追加される最適化された均一ブロックをスキップできます。typearray ビューを直接変更して、デバッグ時に破損に対処したり、構造化コピー機能 ( twgl.setBlockUniforms) を使用したりすることは自由です。

twgl で JavaScript から構造を指定して生成させる必要があるかもしれません。均一なブロック オブジェクトに一致させるのはあなた次第です。これにより、C++ のようになり、1 つのコピーが削除され、デバッグの最適化でブロックが削除されるときに対処しやすくなります。

于 2016-08-09T02:46:17.917 に答える