与OpenGL ES 3不同,没有gl.mapBufferRange
和(存在),在WebGL 2中更新统一缓冲区数据的有效方法是什么?例如,PerDraw统一块gl.bufferSubData
uniform PerDraw
{
mat4 P;
mat4 MV;
mat3 MNormal;
} u_perDraw;
gl.bufferSubData
存在,因此似乎您创建了一个缓冲区然后创建了一个并行的typedArray。更新typedArray并调用gl.bufferSubData
以将其复制到缓冲区中以进行更新并gl.bindBufferRange
使用它。
那可能仍然非常快。首先,所有值操作都保留在JavaScript中,因此调用WebGL的开销更少。如果您有10个要更新的制服,则意味着您要向WebGL发起2次呼叫,而不是10次。
在TWGL.js中,我将所有制服的ArrayBufferViews生成为单个类型的数组,例如,鉴于上面的制服块,您可以执行以下操作
ubo.MV[12] = tx;
ubo.MV[13] = ty;
ubo.MV[14] = tz;
举另一个例子,如果您有一个将数组/类型数组作为目标参数的数学库,则可以执行以下操作
var dest = ubo.P;
m4.perspective(fov, aspect, zNear, zFar, dest);
我遇到的一个问题是统一优化。如果我编辑一个着色器,说我正在调试,我只是插入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对象复制到类型数组的函数,因此我可以跳过任何优化的统一块,不幸的是这会增加一些开销。您可以自由地直接修改类型数组视图,并在调试时处理损坏或使用结构化复制功能(twgl.setBlockUniforms
)。
也许我应该让您从twgl中的JavaScript中指定一个结构,然后生成它,这取决于您是否使它与统一块对象匹配。这将使其更像C ++,删除一个副本,并且在调试优化中删除块时更易于处理。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句