WebGL / OpenGL性能与半使用的顶点缓冲区

时间:2015-01-29 13:58:58

标签: webgl opengl-es-2.0

我有应用程序可以放大/缩小你应该看到很少有高细节的模型或很多低细节的模型。所以我想使用一些LOD技术。

我想知道我是否只使用一个带位置的缓冲区(一个带有法线,......),但每个LOD的索引不同,性能如何?

更确切地说,我想说我想实现5个LOD级别。具有高细节的模型(LOD1)具有~5k个顶点,所有顶点都用于渲染~5k个三角形。低详细模型(LOD5)也会有~5k个顶点,但只有少数几个用于渲染~200个三角形(将使用~2%的数据)。

你见过这个吗?它是否有意义?用于渲染大量少数多边形模型的大数据是否会导致性能下降?

在您提出之前:

运行时使用gpu(另一个画布)生成网格。生成5 LODS作为某种mipmap(我的意思是使用canvas中的最大值来完成所有在一个渲染中执行所有这些http://upload.wikimedia.org/wikipedia/commons/e/ed/Mipmap_illustration2.png)仍然至少比仅生成LOD1慢两倍。在我的情况下,指数优势是它们可以被初始化而不是在运行中生成。

1 个答案:

答案 0 :(得分:1)

一般来说,较少的WebGL调用=更快。因此,例如,如果每个模型的每个模型属性都在不同的缓冲区中,并且让我们说每个模型都有位置,法线,texcoords,顶点颜色。我们假设我们正在使用索引顶点。然后设置绘图调用将需要调用至少9个函数

for each model
  gl.bindBuffer(gl.ARRAY_BUFFER, model.positionBuffer);
  gl.vertexAttribPointer(model.positionLocation, ...);
  gl.bindBuffer(gl.ARRAY_BUFFER, model.normalBuffer);
  gl.vertexAttribPointer(model.normalLocation, ...);
  gl.bindBuffer(gl.ARRAY_BUFFER, model.texcoordBuffer);
  gl.vertexAttribPointer(model.texcoordLocation, ...);
  gl.bindBuffer(gl.ARRAY_BUFFER, model.vertexColorBuffer);
  gl.vertexAttribPointer(model.vertexColorLocation, ...);
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.indexBuffer);
  ...
  gl.drawElements(...);

如果所有这些属性都在同一个缓冲区中,则减少为6个函数

for each model
  gl.bindBuffer(gl.ARRAY_BUFFER, model.buffer);
  gl.vertexAttribPointer(model.positionLocation, ...);
  gl.vertexAttribPointer(model.normalLocation, ...);
  gl.vertexAttribPointer(model.texcoordLocation, ...);
  gl.vertexAttribPointer(model.vertexColorLocation, ...);
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.indexBuffer);
  ...
  gl.drawElements(...);

如果所有型号都在同一个缓冲区中,但需要的偏移量只会略微减少。它现在有5个功能

gl.bindBuffer(gl.ARRAY_BUFFER, model.buffer);
for each model
  gl.vertexAttribPointer(model.positionLocation, ...);
  gl.vertexAttribPointer(model.normalLocation, ...);
  gl.vertexAttribPointer(model.texcoordLocation, ...);
  gl.vertexAttribPointer(model.vertexColorLocation, ...);
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.indexBuffer);
  ...
  gl.drawElements(...);

如果所有模型都使用来自相同缓冲区的索引,那么它甚至会进一步减少到0个函数

gl.bindBuffer(gl.ARRAY_BUFFER, model.buffer);
gl.vertexAttribPointer(model.positionLocation, ...);
gl.vertexAttribPointer(model.normalLocation, ...);
gl.vertexAttribPointer(model.texcoordLocation, ...);
gl.vertexAttribPointer(model.vertexColorLocation, ...);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.indexBuffer);
for each model
  ...
  gl.drawElements(..., model.indexOffset);

当然,设置属性为0。你可能还有几次打电话来设置制服。

所以,从理论上讲,这会更快。但是,这确实假设设置图纸是你的瓶颈。瓶颈往往是其他地方。像GPU(绘制像素)或其他类似碰撞或物理的东西。

当然每一点都有帮助,所以由你决定是否使用索引来分离模型并将所有其余数据放在巨型缓冲区中是一种胜利。它听起来像一个PITA,不值得我,但这只是我的意见

有一点需要注意,WebGL默认只支持16位索引。虽然有an extension that allows 32bit indicesaccording to webglstats.com it's available on 95% of machines that run WebGL