我经常使用WebGL内省,并遇到一些WebGL内省操作的性能问题。这些操作的性能取决于平台和浏览器。现在我正在考虑围绕将执行客户端状态跟踪的WebGL上下文实现瘦包装器。例如,它将存储当前资源绑定,并仅在资源尚未绑定时为资源执行基础gl.bindXXXX()。它还将存储所有资源参数(如属性/统一位置,数组缓冲区大小,顶点属性大小/类型/步幅等)。
这种方法有意义吗?
答案 0 :(得分:1)
第一个问题是你为什么检查东西?如果您的答案是“用于调试”那么这有关系吗?如果您的答案不是“进行调试”,那么为什么呢?你不应该检查任何东西。你应该知道你一直在设置它的状态。
是的,GL内省很慢。这就是你不应该这样做的原因。
至于不设置两次,是的,如果你可以避免设置两次它肯定会更快,但这也假设检查的开销并不慢。例如,如果您执行了20000次操作,并且由于您的检查而仅阻止了200次操作,那么您只需检查20000个内容即可获得200次点击。看起来你们这些19800次检查可能会增加很多开销,而不仅仅是执行你避免的200次多余的调用。
还有其他方法可以避免设置状态两次而不是检查。一个例子是将模型的所有数据放在同一个缓冲区中。然后而不是
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionLoc, ...);
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.vertexAttribPointer(normalLoc, ...);
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.vertexAttribPointer(texcoordLoc, ...);
你只是做
gl.bindBuffer(gl.ARRAY_BUFFER, posTexcoordNormalBuffer);
gl.vertexAttribPointer(positionLoc, ...);
gl.vertexAttribPointer(normalLoc, ...);
gl.vertexAttribPointer(texcoordLoc, ...);
刚刚保存了6次调用WebGL中的2次
另一个例子是不多次设置制服。如果所有着色器都有透视图,相机,视图矩阵等,对于所有模型都没有改变,只需为每个着色器设置一次,而不是每个模型设置一次。构建代码以使其成为可能非常容易,而且检查矩阵是否相同(16次检查)肯定要快得多
但是,接下来的问题是你在做什么需要优化?对于你正在做的事情而言,似乎不太可能是调用WebGL的瓶颈。更常见的是,有更好的技术(比如合并模型)可以获得更少的绘制调用,或者你是GPU绑定的,这意味着你的绘图比GPU可以处理的更多。很少有问题是绘制调用的数量。或者至少这是我的经验。例如,请参阅this article about Deus Ex: Human Revolution。它表明你不需要那么多的绘制调用来制作漂亮的图形。