three.js优化
Three js 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。
three.js 性能优化方面,整理一下常用的优化方法或者方向,供大家一个优化思考的方向
尽量重用Material和Geometry
分时加载
分时加载算法(大数组)
调查显示100ms内的响应能让用户感觉非常流畅。50ms是 Nicholas
针对 JavaScript
得出的最佳经验值。
setTimeout 延时25ms,25ms 保证主流浏览器都顺畅。
可以使用类似的方法来优化three.js程序。
function timedChunk(items, process, context, callback){ var todo = items.concat(); setTimeout(function(){ var start = +new Date(); do { process.call(context, todo.shift()); } while (todo.length > 0 && (+new Date() - start < 50)); if (todo.length > 0){ setTimeout(arguments.callee, 25); } else { callback(items); } }, 25); };
物体的清理
不销毁模型和材质只是单纯的remove的话还是会内存泄漏的.
scene.remove(cube)
cube.geometry.dispose()
cube.matertial.diapose()
合理执行渲染方法.render()
.render()
方法每次执行都需要调用大量的CPU、GPU等硬件资源,所以为了提高渲染性能,可以考虑尽量减少.render()
的执行次数。
如果场景默认是静态的,没有动画,比如展示一个产品、建筑或机械零件的三维模型,只需要在鼠标旋转缩放三维模型,触发.render()
执行即可,在没有发生鼠标事件的时候,可以不执行.render()
对一些有动画的场景,可以适当控制requestAnimationFrame()函数周期
性执行渲染的次数,比如把默认60FBS设置为30FBS。
渲染帧率的优化,其实就是合理调用 render
帧率优化的思路主要是需要时才渲染,无操作时不调用render()。什么时候需要调用渲染呢?主要包含以下情况:
scene中object的增、删、改
object被选中、反选
相机位置、观察点变化
渲染区域大小变化
于是我们需要注意哪些操作会触发这些变化,主要有以下操作:
scene.add/remove方法被调用 (当模型被加载、移除等)
object material的变化,位置、缩放、旋转、透明度等变化
OrbitControls的的变化
camera的 'change'事件
鼠标的 mousedown/mouseup/mousemove等事件
键盘的w/a/s/d/up/down/left/right arrow等
对于大多数一般处于静态的三维场景,可以不一直周期性执行threejs渲染器方法.render(),根据需要执行.render(),比如通过鼠标旋转模型,就通过鼠标事件触发.render()执行,或者在某个时间段出现动画,就在这个时间段周期性执行.render(),过了这个时间段,就恢复原来状态。
比如鼠标控件OrbitControls,当通过OrbitControls控件旋转缩放三维模型的时候,触发渲染器进行渲染。
// 渲染函数 function render() { renderer.render(scene, camera); } render(); var controls = new THREE.OrbitControls(camera); //监听鼠标事件,触发渲染函数,更新canvas画布渲染效果 controls.addEventListener('change', render);
减少没必要执行的代码在周期性渲染函数中的执行
threejs会通过requestAnimationFrame()周期性执行一个渲染函数render(),在渲染函数中除了渲染器.render()方法,其它的尽量放在渲染函数外面,如果必须放在里面的,可以加上if判断尽量加上,不要每次执行render函数的时候,每次都执行没必要执行的代码。
InstancedMesh
在新的threejs版本中,新增加了几个很有意思的Instance类,这里重点挑InstancedMesh来说。InstancedMesh与使用一个geometry共享创建出Mesh是不一样的,InstancedMesh最终达到的效果是一次Drawcall,而共享geometry创建出来的Mesh并无此效果,效率跟不共享创建Mesh渲染性能上没有太大区别,只是可能会省点内存。
InstancedMesh是R110之后出现,有兴趣的可以试试
待更。。。
本文来自博客园,作者:脆,转载请注明原文链接:https://www.cnblogs.com/Wei-notes/p/17120996.html