改善ThreeJS性能的建议

时间:2018-10-20 20:24:08

标签: three.js

我是NASA新的伽马射线星座页面的首席开发人员,该页面是一个交互式的扩展工具,可以突出显示不同波长的夜空。

https://fermi.gsfc.nasa.gov/science/constellations/

Screenshot of the gamma-ray constellation page

我使用ThreeJS组合了交互式内容,尽管页面在现代笔记本电脑上可以正常工作,但我一直在寻找提高旧设备和移动平台性能的方法。

如果这个问题太宽泛,我深表歉意,但是对于在这种应用程序中如何提高ThreeJS效率的任何评论,我将不胜感激。特别是,我很想知道经验丰富的ThreeJS编码器将如何整合/合并几何结构以减少CPU /内存开销。我是一名科学家,担负着程序员的双重职责,因此,对如何改善当前代码性能的任何建议将不胜感激。

这是交互式场景的基本构造方式,但是完整的代码可以在上面的链接中找到:

  1. 创建“天空”球体并对其进行纹理处理
  2. 将相机放置在球体内
  3. 沿着球体创建网格线
  4. 创建光学星座线
  5. 创建伽玛射线星座线
  6. 创建几何以包含星座图
  7. 创建透明的点击捕获几何形状以切换星座图

最终产品具有1083个几何图形,75个纹理,125336个顶点和40642个面。在我的2016 MacBook Pro上浏览页面几分钟,将其加热到足以煎鸡蛋的程度。任何有关使代码更高效的最佳实践的建议都将受到赞赏。

2 个答案:

答案 0 :(得分:3)

您当前正在以每秒60次的速度渲染场景。仅在需要时才进行渲染,可以最大程度地提高性能。

对于静态场景,您只需要在摄像机移动时进行渲染即可-不需要动画循环。

例如,如果您使用OrbitControls来控制相机,则可以使用此模式。

var controls = new THREE.OrbitControls( camera, renderer.domElement );

// call this only in static scenes (i.e., if there is no animation loop)
controls.addEventListener( 'change', render ); 

此外,即使您在演示中使用了TWEEN,也可以使用如下所示的模式仅在补间期间实例化动画循环:

// start animate loop
var id;
animate();

// tween
var time = { t: 0 };
new TWEEN.Tween( time )
    .to( { t : 1 }, 1000 )
    .onStart( function() {
        // custom
    } )
    .onUpdate( function() {
        // custom
    } )
    .onComplete( function() {
        // custom
        cancelAnimationFrame( id );
    } )
    .start();

function animate() {

    id = requestAnimationFrame( animate );

    TWEEN.update();

    render();

}

function render() {

    renderer.render( scene, camera );

}

three.js r.97

答案 1 :(得分:1)

根据视图位置和角度,您的应用程序每帧最多可产生600个绘制调用。通过在浏览器控制台中输入renderer.info.render,您可以轻松地看到这一点。性能优化方面的一个很好的起点是减少绘制调用。您可以通过多种方式执行此操作,例如通过使用实例化渲染或避免使用多个材质对象将多个几何合并为一个几何。如果您的应用程序受CPU限制,减少绘图调用可以大大提高3D应用程序的性能。

由于您使用的是three.js R84,因此建议您升级到最新版本。今年,我们实施了一些性能功能,例如统一缓存或在混合环境中避免了冗余状态更改。这样的东西也可能会对您的应用程序的性能产生积极影响。

顺便说一句:three.js forum中有许多有关性能优化的有趣讨论。