【发布时间】:2014-01-24 17:24:35
【问题描述】:
嘿,我正在开发一个 webgl 应用程序,它需要动态生成大量 2d 几何图形,例如折线、复杂的多边形。目前使用的顶点/颜色/索引/纹理坐标是预先分配的,然后根据主更新循环中的用户输入进行计算。
我尽量回收利用,例如。绘制 150000 个圆圈时,我尝试确保仅计算一次几何/颜色/texcoords/索引,除非基本参数(圆圈细节,...)不改变,然后平移、缩放(x&y)、旋转此“圆形蓝图”的顶点(移动索引并设置顶点颜色)x 倍于用户指定的数量。
之后通过一个 drawArrays/drawElements 调用发送数据。绘制折线和其他图元的处理方式类似。
虽然这已经相当快了,但显然很多时间都花在了将原始顶点转换为新的位置和尺寸上,有时只留下少量资源供用户用于实际构建要显示的东西。
所以我问自己我怎样才能外包那些“简单”的计算。在考虑以 gpgpu 方式进行之前,我曾考虑将这些计算转移到网络工作者身上。
这就是我的想法:
- 主线程:用户发送请求绘制 150000 个圆,提供尺寸、变换和颜色
- 主线程:请求被推送到绘制请求队列
- 主线程:请求数据被发送到 web worker(如果 worker 尚未启动或完成之前的队列项)
- 网络工作者:正在使用足够大的预分配数据集来构建几何并对其进行转换
- web worker:传输转换后的 Float32Array 顶点、颜色数据和 Uint16Array 索引数据通过 可转移对象到主线程
- 主线程:onWorkeRequestProcessed:获取worker发送的数据,发送到glDrawArrays/glDrawElements调用, 将数据发回给工作人员
- 网络工作者:接收回数据,将“好的,一切都恢复原状,我准备好接受另一个请求”消息发送到主线程
- 主线程:移动队列,从前面发送下一个请求
... 所以最后希望有更多资源可用于主线程来执行一些用户发起的计算。
这样做意味着主循环总是必须等到工作人员完全处理完队列线性后才能以正确的顺序绘制所有内容,这最终可能会使使用工作人员的优势过时。
这是我目前所拥有的:https://gist.github.com/automat/8566773(没有 webgl 部分,只有消息队列,没有主循环,因为同步 framestep 和等待 worker 也是一个问题)
顺便说一句:通过纹理四边形假实例化几何实体不是一种选择。
你可以看看这里的项目:https://github.com/automat/canvasGL.js(src/gl/cglContext.js 应该特别有趣)
这有什么好处吗?任何提示表示赞赏...
【问题讨论】:
标签: javascript optimization webgl web-worker