1、网格模型合并
此合并不是把几个网格模型放到一个组中,而是进行uv,顶点,矩阵的合并;做个实验,在普通组中,渲染20000个几何体,帧率一般在15帧左右,如果选择合并在绘制20000个几何体,帧率会大大的提高;下面是合并的方法,应为threejs的版本问题,合并的方法一直调用失败,因此写了下来,请大家帮忙看看哪地方出问题了:
//网络模型合并 three:0.139.2版本
//引用此版本,会有THREE is not defined 的报错
// import {mergeBufferGeometries,mergeBufferAttributes} from'three/examples/jsm/untils/BufferGeometryUtils.js' 如此引用也会报错
import {BufferGeometryUtils} from 'three/examples/js/untils/BufferGeometryUtils.js'
function createModel(){
let box=new THREE.BoxGeometry(10,10,10);
let material=new THREE.MeshBasicMaterial({
color:0xffffff
})
let mesh=new THREE.Mesh(box,material);
let geometryArray = []; // 将你的要合并的多个geometry放入到该数组
let materialArray = []; // 将你的要赋值的多个material放入到该数组
for(let i=0;i<2000;i++){
let boxMesh=mesh.clone();
boxMesh.position.set(Math.random()*1000,Math.random()*1000,Math.random()*1000);
geometryArray.push(boxMesh.geometry);
materialArray.push(boxMesh.material);
}
// 合并模型
const mergedGeometries = BufferGeometryUtils.mergeBufferGeometries(geometryArray, true);
const singleMergeMesh = new THREE.Mesh(mergedGeometries, materialArray);
scene.add(singleMergeMesh)
}
缺点:组能够对每个单独的个体进行操作,而合并网格后则失去对每个对象的单独控制。想要移动、旋转或缩放某个方块是不可能的。
2、重用材质和模型
一般材质相同,模型相同的时候会这么做,进行拷贝或者克隆一个相同的网格模型出来,这样做有一个不太好的地方就是:如果你点击一个模型想修改模型颜色,这个时候不能使用mesh.material.color来修改,否则会把克隆出来得模型颜色都修改了;得重新创建一个材质进行赋值
//不断循环创建渲染
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);
}
//材质几何体只创建一次,或者clone()拷贝,设置定位
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);
mesh.position.set(Math.random()*1000,Math.random()*1000,Math.random()*1000)
scene.add(mesh);
}
3、# requestAnimationFrame()的使用
requestAnimationFrame()这个方法大概每秒运行60次,如果要在这里方法里面添加for循环的处理,可能会造成浏览器崩溃,所以在这个方法中尽可能的不要使用for循环,而且一些着色器的参数改变要添加判断,在需要的时候才进行执行;寻找一个平衡点,使得运行次数没那么高,还不影响操作,俗称跳帧一般设置为30ms执行一帧
let clock=new THREE.Clock();
let renderT=1/30;
let timeS=0;
function animate(){
let T=clock.getDelta();
timeS+=T;
if(timeS>renderT){
this.renderer.render(this.scene,this.camera);
timeS=0;
}
requestAnimationFrame(animate)
}
4、切换模型时,删除模型中多余的naterial 材质,纹理,几何体
//删除几何体
mesh.geometry.dispose();
//删除纹理贴图
mesh.textture.dispose();
//删除材质;有时候材质为数组,这个时候就需要循环材质进行删除了
mesh.material.dispose();
5、模型面数与纹理贴图
模型的面数约少越好,模型越细腻渲染的时候开销就越大,计算量就越大;纹理图片尺寸一定得是2的幂次方,并尽可能的小,加载纹理贴图时,如果不是2的幂次方,那么three.js就会自动转为最合适的2的幂次方尺寸,并在控制台打印出黄色警告。这个不是three.js设置的,是webgl限制的,是为了适合Mipmap(为了加快渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件)设置。
总结
模型大的话,这些优化几乎都不管用,可以考虑切模型,把大的模型切成一个个小的模型,然后在渲染的时候不做任何处理,使每个模型都按照且之前的位置排好;