opengl-es - 在每一帧上更新整个 VBO 是绘制许多变化的独特三角形的最有效方法吗?

标签 opengl-es webgl

my previous question 的答复建议我使用顶点缓冲区对象并将位置数据与颜色数据合并到单个数组中,我现在已经在这个简单的测试用例中完成了:

http://jsfiddle.net/headchem/r28mm/14/

每一帧的伪代码:

function drawFrame() {
    // clear global vertex[] array containing both position and color
    // recreate it with new triangles and colors (determined elsewhere)
    drawShapes();

    // put the vertex array into the VBO using gl.bufferData
    // finish with a single call to gl.drawArrays(gl.TRIANGLES, 0, numItems);
    render();
}

我知道没有 Elixir ,但对于我渲染一个充满变化的独特三角形的屏幕的目标来说,这是最有效的方法吗?使用 bufferSubData 会比 bufferData 提供任何好处吗?

当我在动画循环中对此进行测试时,我可以在帧速率受到影响之前每帧更新大约 800 个三角形。当我想要在每一帧上都有独特且不断变化的三角形时,这是否是我能做的限制?我看到人们抛出更大的数字,例如 50k 三角形 - 是因为他们能够在显卡上缓存顶点数组,并且不需要更改每个帧上的每个顶点和颜色?使用 canvas api 时,我可以在帧率下降之前绘制 1500 个不同颜色和位置的矩形 - 我的 WebGL 做错了什么,canvas api 的性能优于它?

最佳答案

我查看了您的代码,发现您的 JavaScript 效率很低。例如,重复执行的这一行:

convertedVerts = convertedVerts.concat(getConvertedVerts(pxVerts, zIndex, color));

可能效率极低:程序的简单执行需要 O(n^2) 时间,其中 n 是顶点数,因为每次运行该行时都会将元素复制到新数组中。

通过将其更改为以下内容,我在 Firefox 和 Safari 上的性能得到了很大提高(Chrome 似乎并不关心,可能是因为它优化了复制):

convertedVerts.push.apply(convertedVerts, getConvertedVerts(pxVerts, zIndex, color));

更好的方法是更改​​ getConvertedVerts,以便将数组推送到而不是创建并返回数组。

但是,您的程序可能应该编写的方式是分配一个 Float32Array 一次,然后直接向其中写入新值(传递数组和起始索引)周围)在每一帧中。避免创建新数组,尤其是避免每一帧创建新的 Float32Array,更不用说每个顶点了。

我还建议您摆脱中间的 Canvas 模拟步骤(例如构造 rgba() 颜色,然后再次解析它)——不过,没有理由在代码中进行任何字符串操作这并不像上面的算法效率低下那么严重。

关于opengl-es - 在每一帧上更新整个 VBO 是绘制许多变化的独特三角形的最有效方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24616756/

相关文章:

android - OpenGL ES glCheckFramebufferStatus 返回 0

java - 设置 2D OpenGL ES 渲染器?

java - 在 glOrtho View 中绘制一条线,为什么它使用默认投影?

javascript - 在我的主机中加载 3D 模型时出现问题

javascript - 如何使用 gl.readPixels 读取点数 > 1 的绘制的 gl.POINTS?

arrays - 我应该从结构和类切换到数组吗?

java - Libgdx 用纹理重构一个类

javascript - 无法让 Unicode 字体与 Three.js TextGeometry 一起使用

webgl - WebGL 中透明纹理的奇怪渲染行为

javascript - Webgl Chrome 空白 Canvas