webgl2 - 更新 WebGL 2 中的统一缓冲区数据?

标签 webgl2

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

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

最佳答案

gl.bufferSubData 存在,因此看起来您创建了一个缓冲区,然后创建了一个并行类型数组。更新 typedArray 并调用 gl.bufferSubData 将其复制到缓冲区中以进行更新,并 gl.bindBufferRange 使用它。

可能仍然非常快。首先,所有值操作都保留在 JavaScript 中,因此调用 WebGL 的开销更少。如果您有 10 个制服需要更新,则意味着您要对 WebGL 进行 2 次调用,而不是 10 次。

TWGL.js我将所有制服生成 ArrayBufferViews 到单个类型数组中,因此例如给定上面的制服 block ,您可以这样做

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; 在片段着色器的顶部,一些统一 block 被优化,代码将被破坏。我不知道 C/C++ 项目中处理此问题的标准方法是什么。我想在 C++ 中你会声明一个结构

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

所以问题就消失了。在 twgl.js 中,我在运行时有效地生成该结构,这意味着如果您的代码期望它存在,但它没有生成,因为它已经过优化,然后代码中断。

在 twgl 中,我创建了一个从 JavaScript 对象复制到类型化数组的函数,这样我就可以跳过任何优化的统一 block ,不幸的是,这增加了一些开销。您可以直接修改类型数组 View 并在调试时处理损坏问题,或者使用结构化复制功能 (twgl.setBlockUniforms)。

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

关于webgl2 - 更新 WebGL 2 中的统一缓冲区数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38841124/

相关文章:

angular - 禁用浏览器中的图像缓存

javascript - 如何在 webgl2 中使用深度纹理

webgl2 - 如何使用统一缓冲区对象和实例化渲染来绘制多个对象?

javascript - 无法在 webgl 中将 Canvas 渲染为纹理,但可以渲染蓝色

javascript - 如何从不属于我的 Canvas 中获取像素数据?

javascript - WebGL2中浮点纹理的线性过滤

javascript - WebGL 2.0 GLSL 在使用 sampler3D 时遇到语法错误

webgl - WebGL:异步操作?

google-chrome - WebGL2 支持的显卡

javascript - WebGL 2.0 支持短 3D 纹理