首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CPU上的预计算顶点

CPU上的预计算顶点
EN

Stack Overflow用户
提问于 2017-05-08 16:40:23
回答 1查看 50关注 0票数 0

对于使用WebGL呈现许多精灵,我想我会问性能问题。

让我们考虑一下这一点:

代码语言:javascript
复制
for(let i = 0; i < 50000; i++){
    let t = new Sprite();
    t.scale(Math.random())
    t.rotate(Math.random())
    t.transform(Math.random(),Math.random())

具有scalerotatetransform的下列函数

代码语言:javascript
复制
 translate(x, y) {
    for (let i = 0; i < this.vertexData.length; i += 3) {
      this.vertexData[i] += x;
      this.vertexData[i + 1] += y;
    }
  }


  rotate(alpha) {
    this.translate(-this.position[0], -this.position[1]);
    for (let i = 0; i < this.vertexData.length; i += 3) {
      let new_x = this.vertexData[i] * Math.cos(alpha) - this.vertexData[i + 1] * Math.sin(alpha);
      let new_y = this.vertexData[i + 1] * Math.cos(alpha) + this.vertexData[i] * Math.sin(alpha);
      this.vertexData[i] = new_x;
      this.vertexData[i + 1] = new_y;
    }
    this.translate(this.position[0], this.position[1]);
  }


  scale(factor) {
    this.translate(-this.position[0], -this.position[1]);
    for (let i = 0; i < this.vertexData.length; i += 3) {
      this.vertexData[i] *= factor;
      this.vertexData[i + 1] *= factor;
    }
    this.translate(this.position[0], this.position[1])
  }

this.vertexData=[-1, -1, 0, 1, -1, 0, -1, 1, 0, -1, 1, 0, 1, -1, 0, 1, 1, 0];

让函数scalerotatetransform更快的可能性是什么?要么取决于语言,要么取决于数学。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-09 02:39:06

  1. 将所有精灵的所有精灵数据放在一个数组中。每个精灵使用一个数组。这意味着您必须为每个雪碧的gl.bufferData分别调用vertexData。这比一次上传所有精灵的所有精灵数据的调用要慢。 如果您仍然希望每个sprite保留一个对象,则可以让每个sprite使用一个偏移量到一个更大的全局数组中。 const maxSprites = 50000;const globalVertData =新Float32Array(maxSprites * 12);const quad = -1,-1,-1,-1,-1,1,1,-1,1,- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1;const numSprites = 0;类雪碧{构造器{ const偏移量= numSprites++ * 12 * 4;//使vertexData视图进入大数组this.vertexData =新的Float32Array( globalVertData.buffer,偏移量,12);this.vertexData.set(quad);} ..。你的职能从上面.} 或者这个 const maxSprites = 50000;const globalVertData =新Float32Array(maxSprites * 12);const quad = -1,-1,-1,-1,-1,1,-1,- 1,1,- 1,- 1,1,-1,-1,1,-1,1,1,1,1,1,1,1;const numSprites = 0;class Sprite {构造函数{ this.offset = numSprites++ * 12;globalVertData.set(quad,this.offset);} translate(x,y) { let i= this.offset;const end =i+ 12;for (;i< end;I += 2) { globalVertDatai += x;globalVertDatai +1 += y;}.使用this.offset .}的旋转和缩放函数 然后,您只需将globalVertDatagl.bufferData一起上传,而不是每一个雪碧的vertexData。 我有直觉,第二种比第一种更快。这还需要更少的内存,因为每件事都有一个数组对象而不是一个数组视图。那就是说我没有测试它所以我可能错了。
  2. 摆脱Z。假设你不需要Z作为精灵,摆脱它(看起来你不需要它,因为既不旋转,也不平移,操纵z)。然后你就会上传更少的数据,至少scale会变得更快。我在上面做的。
  3. 从你的循环中抽出长度 for (设i= 0;i< someArray.length;++i) {. 比 someArray.length;for (设i= 0;i< len;++i) { 这也比 spriteLen = 12;//全局或闭变量const len = spriteLen;for (设i= 0;i< len;++i) {. 基本上,.操作符需要时间,就像在array.lengthfoo.bar中一样。在第一个例子中,.操作符每次迭代都会发生。在第二个循环中,每个循环发生一次。在第三阶段,它根本没有发生。
  4. letvar让我们在循环的每一次迭代中创建一个新对象。Var不,尽管如果你把它从循环中拉出来,这个问题就会消失。将来浏览器可能会修复这个问题,因为它们可以分析代码,并看到它们不需要每次迭代都创建一个新对象(Spidermonkey似乎是这样做的,Chrome 60似乎也是这样做的。狩猎旅行--它还是慢一点)
  5. 其他通常能帮助精灵的东西。使用纹理地图集。这样你就可以通过一次抽签就可以画出所有的精灵。

您可能会发现这个答案也很有用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43852943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档