【问题标题】:Updating Uniform Buffer Data in WebGL 2?在 WebGL 2 中更新统一缓冲区数据?
【发布时间】:2016-12-14 22:22:20
【问题描述】:

与OpenGL ES 3不同,没有gl.mapBufferRange gl.bufferSubData(存在),在WebGL 2中更新统一缓冲区数据的有效方法是什么? 例如,PerDraw Uniform 块

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

【问题讨论】:

  • gl.bufferSubData 存在
  • 我的错。它已经在 WebGL 1 中,这就是我在 WebGL 2 规范中找不到的原因。

标签: webgl2


【解决方案1】:

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 对象复制到类型化数组的函数,因此我可以跳过任何优化的统一块,不幸的是这会增加一些开销。您可以直接修改 typearray 视图并在调试时处理损坏或使用结构化复制功能 (twgl.setBlockUniforms)。

也许我应该让你在 twgl 中从 JavaScript 中指定一个结构并生成它,并由你决定让它与统一的块对象匹配。这会让它更像 C++,删除一个副本,并且在调试优化删除块时更容易处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多