【问题标题】:WebGL performance problems with a >65k vertex mesh on a MacBook ProMacBook Pro 上 >65k 顶点网格的 WebGL 性能问题
【发布时间】:2014-11-25 22:04:41
【问题描述】:

以下模型在几款低端机器上表现不错:

http://examples.x3dom.org/example/x3dom_sofaGirl.html

但是,在配备 Nvidia GT 650m 的 MacBook Pro 上,帧速率非常低。我认为这是因为 MacBook 没有 OES_element_index_uint 扩展名,但如果我这样做了,则会显示扩展名:

document.createElement("canvas").getContext("experimental-webgl").getSupportedExtensions();

重构低于 65K 的网格可以解决问题。有没有什么办法不用重组也能有好的表现?

我安装了一个应用程序 (gfxCardStatus),它禁用了 GT 650m 并强制只使用集成显卡。现在,一切正常。这是驱动程序错误吗?

我发现另一个 3d 场景在专用 GPU 上比在集成 GPU 上运行得更快:

http://examples.x3dom.org/binaryGeo/oilrig_demo/index.html

我认为这是因为它由许多小网格组成。此外,当我运行这个场景时,我可以听到 GPU 风扇转动的声音。沙发女孩场景没有。

【问题讨论】:

  • 您必须使用 uint 进行索引吗?您可以编写一个包装器,将一个大网格自动批处理到多个 drawElements 调用中。根据我绘制大量立方体的经验,这样做的开销非常小。
  • 我不必。事实上,根据他们的文档,我认为 X3DOM.js 框架实际上确实将其拆分。无论如何,它在 MacBook 上仍然很慢。

标签: webgl nvidia x3dom webgl-extensions


【解决方案1】:

首先,WebGL 不限于每次绘制调用 65k 个顶点。 gl.drawElements 有一个 64k 的限制,尽管有一个扩展可以消除这个限制。 gl.drawArrays 没有这个限制。

我不知道为什么它很慢,但是查看WebGL Inspector X3DOM 中的帧正在使用gl.drawArrays

我又挖了一点。我尝试使用 Web Tracing Framework 以及 Chrome 的分析器。它显示在gl.readPixels 上花费了很多时间。

为了查看这是否是问题,我打开了 JavaScript 控制台并将 gl.readPixels 替换为这样的无操作

在 JavaScript 控制台中:

// find the canvas
c = document.getElementsByTagName("canvas")[0]

// get the webgl context for that canvas
gl = c.getContext("webgl")

// replace readPixels with a no-op
gl.readPixels = function(x, y, w, h, f, t, b) { 
  var s = w * h * 4; 
  for (var ii = 0; ii < s; ++ii) {
    b[ii] = 0;
  }
};

这删除了readPixels 在分析器中的显示

但示例并没有运行得更快。

接下来我尝试破解 drawArrays 以减少绘制次数。

在 JavaScript 控制台中:

// save off the original drawArrays so we can call it
window.origDrawArrays = gl.drawArrays.bind(gl)

// patch in our own that draws less
gl.drawArrays = function(t, o, c) { window.origDrawArrays(t, o, 50000); }

你知道吗,现在它运行得非常快。唔。也许这是一个驱动程序错误。它被要求绘制 1070706 个顶点,但这对于 NVidia GT 650m 来说似乎不是一个大数字


所以,我不知道为什么,但我想研究这个问题。我编写了一个本机应用程序来显示相同​​的数据。它以 60fps 轻松运行。我像OP所说的那样检查了WebGL中的集成图形。也很容易达到60fps。 NVidia 650GT 的速度约为 1fps。

我还检查了 Safari 和 Firefox。他们也运行得很慢。常见的是角度。他们都使用 ANGLE 来重写着色器。也许那里有一个问题,因为同一个着色器在我的本机测试中运行良好。当然,Native 测试与 WebGL 做的事情并不完全相同,但它不仅仅是绘制 1M 多边形。

所以我提交了一个错误: https://code.google.com/p/chromium/issues/detail?id=437150

【讨论】:

  • 感谢您的调查。 window.origDrawArrays(t, o, 50000);只绘制一小块网格。是否可以多次调用它作为解决方法?
  • 刚刚尝试过,不幸的是没有帮助。
  • 我在原始帖子中添加了另一个更新。如果我想使用 Nvidia 卡,我想我必须事先拆分网格。
  • 我怀疑分割网格会有所帮助,因为这可以说与让 drawArrays 一次渲染 50k 多边形没有什么不同。问题似乎是着色器。这让 NVidia 不高兴了。
  • @gman 你有没有发现是什么导致了减速?多年来我一直受到这个问题的影响,但似乎没有人关心或对此有答案? :O
猜你喜欢
  • 2015-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
  • 2011-01-24
  • 2022-06-16
  • 2019-06-30
相关资源
最近更新 更多