Opengl es 在每个帧上更新整个VBO是否是绘制许多变化的唯一三角形的最有效方法?

Opengl es 在每个帧上更新整个VBO是否是绘制许多变化的唯一三角形的最有效方法?,opengl-es,webgl,Opengl Es,Webgl,答案建议我使用顶点缓冲区对象并将位置数据和颜色数据合并到单个数组中,我现在已经在这个简单的测试用例中完成了: 每帧的伪代码: function drawFrame() { // clear global vertex[] array containing both position and color // recreate it with new triangles and colors (determined elsewhere) drawShapes();

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

每帧的伪代码:

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似乎并不在意,可能是因为它优化了复制过程):

更好的做法是更改
getConvertedVerts
,这样就可以将数组推到上面,而不是创建并返回一个数组

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


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

Wow!我实现了你所有的建议(),三角形计数变得疯狂。现在我的笔记本电脑可以在帧速率降低之前绘制100000个三角形。我错误地认为我的问题出在WebGL上。感谢您向我展示这些javascript优化!
convertedVerts.push.apply(convertedVerts, getConvertedVerts(pxVerts, zIndex, color));