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

2024-05-12

答复我之前的问题 https://stackoverflow.com/questions/24592099/drawing-many-unique-triangles-with-a-single-draw-call-for-better-performance/24605055建议我使用顶点缓冲区对象并将位置数据与颜色数据合并到单个数组中,我现在已经在这个简单的测试用例中完成了:

http://jsfiddle.net/headchem/r28mm/14/ 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();
}

我知道没有灵丹妙药,但对于我渲染一个充满变化的独特三角形的屏幕的目标来说,这是最有效的方法吗?使用 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 once,然后在每个帧中直接将新值写入其中(传递数组和起始索引)。避免创建新数组,尤其是避免创建新数组Float32Arrays,每一帧,更不用说每个顶点了。

我还建议您摆脱中间的画布模拟步骤(例如构造 rgba() 颜色,然后再次解析它)——没有理由在代码中进行任何字符串操作,尽管这不是'这几乎与上述算法效率低下一样严重。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐