博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
three.js 性能优化的几种方法
阅读量:5051 次
发布时间:2019-06-12

本文共 4862 字,大约阅读时间需要 16 分钟。

本篇介绍three.js性能优化的若干方法。(个人拙见)

three.js性能优化

尽量重用Material和Geometry

这里以Material和Geometry为例(使用比较频繁)

for (var i = 0; i < 100; i++) {        var material = new THREE.MeshBasicMaterial();        var geometry = new THREE.BoxGeometry(10, 10, 10);        var mesh = new THREE.Mesh(geometry, material);        scene.add(mesh);    }

改为

var material = new THREE.MeshBasicMaterial();    var geometry = new THREE.BoxGeometry(10, 10, 10);    for (var i = 0; i < 100; i++) {        var mesh = new THREE.Mesh(geometry, material);        scene.add(mesh);    }

谨慎的在render()中操作

一般FPS为60也就意味着一秒会执行60次如果render()中有有实例化或是赋值操作很容易会崩溃。

如下:

function render() {        material.map = canvasMap;    material.map.needsUpdate = true;    }

选择合适的对象

  • THREE.ParticleSystem(粒子系统)代替THREE.Particle(粒子)
for (var x = -5; x < 5; i++) {        for (var y = -5; y < 5; y++) {            var particle = new THREE.Particle(material);            particle.position.set(x * 10, y * 10, 0);            scene.add(particle);        }    }

代替

var geometry = new THREE.Geometry();    var material = new THREE.ParticleBasicMaterial();    for (var x = -5; x < 5; i++) {        for (var y = -5; y < 5; y++) {            var particle = new THREE.Vector3(x * 10, y * 10, 0);            geometry.vertices.push(particle);        }    }    var system = new THREE.ParticleSystem(geometry,material);    scene.add(system);
  • 要操作一组对象时使用 THREE.Object3D
var contain = new THREE.Object3D();     var material = new THREE.MeshBasicMaterial();    var geometry = new THREE.BoxGeometry(10, 10, 10);    for (var i = 0; i < 100; i++) {        var mesh = new THREE.Mesh(geometry, material);        contain.add(mesh);    }        contain.rotation.x = Math.PI/3;
  • 网格合并 THREE.GeometryUtils.merge

R60

var geometry = new THREE.BoxGeometry(5, 5, 5);        var material = new THREE.MeshBasicMaterial({color: 0xff0000});        for (var i = 0; i < 100; i++) {            THREE.GeometryUtils.merge(geometry, new THREE.BoxGeometry(5, 5, 5));        }        var mesh = new THREE.Mesh(geometry, material);        scene.add(mesh);

或是一下方式(geometry有位置信息)

var geometry = new THREE.BoxGeometry(5, 5, 5);        var material = new THREE.MeshBasicMaterial({color: 0xff0000});                var mesh = new THREE.Mesh(geometry,material);        mesh.position.set(10,10,10);                var mGeo = new THREE.BoxGeometry(10, 2, 10);                THREE.GeometryUtils.merge(mGeo, mesh);           scene.add(new THREE.Mesh(mGeo, material));

R80 THREE.GeometryUtils.merge() change to geometry.merge()

var geometry = new THREE.BoxGeometry(2, 4, 2);                        var mGeo = new THREE.BoxGeometry(5, 5, 5);                var matrix = new THREE.Matrix4();                for(var i=0;i<100;i++){                    matrix.setPosition(new THREE.Vector3(Math.random()*10,0,Math.random()*10));                geometry.merge(mGeo, matrix);            }                   var mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({color: 0xff0000}));            scene.add(mesh);

使用Web Workers

web worker 是运行在后台的 JavaScript,它独立于其他脚本,不会影响页面的性能

我们会发现Physijs物理库就是使用这种方式来保证页面的性能。

使用之前你可能需要是否支持web worker

if(typeof(Worker)!=="undefined"){}else { }

我们将web worker运行脚本放在一个js文件中。

three_workers.js:

// 添加监听事件,从主线程接收数据    self.addEventListener('message', function(event) {                // 向主线程发送数据        self.postMessage({            some_data: '',            more_data: ''          })        })

主线程.js:

//新建一个 `Web Workers`        var worker = new Worker('three_workers.js');         // 添加监听事件,获取`Web Workers`传回数据     worker.addEventListener('message', function (event) {           var data = event.data;          });        // 向`Web Workers`发送数据    worker.postMessage({        some_data: '',      more_data: ''    });

可以参照:

function timedChunk(items, process, context, callback){

var todo = items.concat(); //create a clone of the original

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);

}

分时加载

可以参照:

分时加载算法(大数组)

调查显示100ms内的响应能让用户感觉非常流畅。50ms是 Nicholas 针对 JavaScript 得出的最佳经验值。

setTimeout 延时25ms,25ms 保证主流浏览器都顺畅。

可以使用类似的方法来优化three.js程序。

//Copyright 2009 Nicholas C. Zakas. All rights reserved.//MIT Licensedfunction 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);};

程序分析见

使用自定义着色器

以后会有一篇专门讲着色器

转载于:https://www.cnblogs.com/chenjy1225/p/9640562.html

你可能感兴趣的文章
03 SeekBar 音频播放拖拽进度条
查看>>
自定义view实现阻尼效果的加载动画
查看>>
清北学堂的小技巧和小收获
查看>>
模型压缩方向一个很牛的paper
查看>>
Android--AsyncTask异步加载详解
查看>>
YARN学习总结
查看>>
C#基础温习(2):温习控制台程序(二)
查看>>
一些文章
查看>>
注解@ResponseBody的作用
查看>>
java main函数不执行?
查看>>
iOS 更好用的打Log方式-显示文件名、行数
查看>>
从MS SQL删除大数据说开去
查看>>
NOVO SOP (SOP简介及历史)
查看>>
windows7+docker添加php扩展
查看>>
V2019 Super DSP3 Odometer Correction Vehicle List
查看>>
Python 3.X 练习集100题 05
查看>>
今时不同往日:VS2010十大绝技让VS6叹服
查看>>
设计器 和后台代码的转换 快捷键
查看>>
在线视频播放软件
查看>>
用代码生成器生成的DAL数据访问操作类 基本满足需求了
查看>>