Three.js多细节层次LOD
开发Web3D应用的时候,在一个很大的场景中有一个物体通过一个网格模型Mesh
表示,为了追求更好的性能,在显示效果相近的情况下,可以根据网格模型Mesh
距离相机镜头的远近来设置网格模型绑定几何体Geometry的三角形面数或者说顶点数量,面数越多显示效果肯定越精细,不过距离比较远的情况下,适当降低曲面三角形面数,在渲染性能提高的同时,低面数也可以做到高面数近似的显示效果。
比如说一个球体你可以用50个三角形面描述,也可以用200个三角形面,距离相机镜头比较近的情况下,使用200个三角形面面数球体效果比较好,如果离得比较远,同样渲染效果下为了更好的渲染性能,也没必要还设置为200个三角形面,可以适当减少面数。
为了实现距离相机远近不同,使用不同三角形面数的网格模型,Three.js引擎封装了一个类多细节层次THREE.LOD
来实现该功能,多细节层次概念对应的英文是Levels of Detail。关于THREE.LOD
类的介绍可以参考Threejs官方文档object(物体)分类下关于THREE.LOD
的介绍。
代码案例
下面的代码创建三个三角形面数不同的球体网格模型,然后通过多细节层次模型THREE.LOD
来设置远近不同距离显示哪一个球体网格模型,距离比较远显示低面数球体网格哦行,距离比较近,显示高面数网格模型。
var scene = new THREE.Scene();
// 创建一个多细节层次模型对象LOD
var lod = new THREE.LOD();
// 近距离——高面数网格模型球体
var geometry1 = new THREE.SphereGeometry(50, 25, 25)
var material1 = new THREE.MeshPhongMaterial({
color: 0xff0000,//使用红色标记高面数网格模型
});
var mesh1 = new THREE.Mesh(geometry1, material1);
// 细节层级距离100,距离相机比近显示该网格模型
lod.addLevel(mesh1, 100);
// 中距离——中面数网格模型球体
var geometry2 = new THREE.SphereGeometry(50, 20, 20)
var material2 = new THREE.MeshPhongMaterial({
color: 0x00ff00, //使用绿色标记中面数网格模型
});
var mesh2 = new THREE.Mesh(geometry2, material2);
// 细节层级距离300,距离相机中等距离显示该网格模型
lod.addLevel(mesh2, 300);
// 远距离——低面数网格模型球体
var geometry3 = new THREE.SphereGeometry(50, 15, 15)
var material3 = new THREE.MeshPhongMaterial({
color: 0x0000ff, //使用蓝色标记低面数网格模型
});
var mesh3 = new THREE.Mesh(geometry3, material3);
// 细节层级距离500,距离相机比较远显示该网格模型
lod.addLevel(mesh3, 500);
// 控制台查看多细节层次模型对象Lod
// 你可以看到Lod对象的.children属性包含了上面.addLevel方法插入的三个网格模型mesh1,mesh2,mesh3
console.log(lod)
// 改变物体距离相机不同距离,可以看到不同面数的网格模型Mesh,
// 可以改变z的值进行测试,上面三个不同面数的球体网格模型使用了不同的颜色进行标记,便与测试
// 设置z的值改变球体网格模型的位置,注意相机参数 200 -100 -300
lod.position.z = -300
// 把多层次细节模型对象lod插入到场景中,lod虽然包含多个子对象网格模型,通常显示一个
// 注意渲染函数render中执行lod的更新方法.update(camera)
scene.add(lod);
...
...
function render() {
// 注意渲染函数render中执行lod的更新方法.update(camera)
lod.update(camera)
renderer.render(scene, camera);
requestAnimationFrame(render);
}
为了便于进行代码测试,注意相机参数的设置
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 3000);
camera.position.set(0, 0, 300);
多层次细节LOD
多层次细节模型对象LOD
和组对象Group
一样基类是Object3D
,为了你能够更快的使用好LOD
类,可以类比过去的Threejs知识点进行快速学习记忆。你可以简单的把多层次细节模型对象LOD
理解为组对象Group
,组对象Group
可以通过.add()
方法插入一个网格模型对象作为group的子对象,也就是插入到.children
属性中,对于多层次细节对象LOD
是一样的,只是
LOD
使用的方法不是.add()
而是.addLevel()
,.addLevel()
和.add()
一样改变的是父对象的.children
属性。
你可以把把多层次细节模型对象LOD
简单的理解为组对象Group
,区别在于组对象Group
属性.children
中的子对象默然是全部渲染的,多层次细节模型对象LOD
属性.children
中的子对象Threejs系统一般要根据距离计算显示其中一个。
.addLevel(模型对象,距离)
方法
多层次细节LOD
模型对象的.addLevel()
方法,类似组对象或场景对象的.add()
方法,会改变LOD
对象的.children
属性,.addLevel()
方法的参数1会插入.children
属性数组中,
.addLevel()
方法的参数2用来设置参数1表示的模型对象在多少距离下显示,执行该方法lod对象的.levels
数组属性会多一个元素对象。
// 细节层级距离300,距离相机300以内显示该网格模型
// 执行该方法,lod对象的`.levels`数组属性会多一个元素对象{distance: 300, object: Mesh}
lod.addLevel(mesh2, 300);
.levels
属性
.levels
属性值是一个数组,数组中有多个细节不同模型对象相关参数,数组元素是一个对象,有object和distance两个属性,object指向一个模型对象,distance表示该模型对象显示的临界距离。
每执行一次.addLevel(模型对象,距离)
方法,.levels
属性就多一个元素对象,.addLevel()
的两个参数值分别原来设置.levels
元素的object和distance属性
为了更好的了解lod对象的数据结构,可以在控制打印该对象,查看lod对象的每一个属性,尤其是 .levels
属性,Threejs系统渲染的时候,会从Lod的属性中各个参数,控制渲染结果。
// 控制台查看多细节层次模型对象Lod
// 你可以看到Lod对象的.children属性包含了上面.addLevel方法插入的三个网格模型mesh1,mesh2,mesh3
console.log(lod)
.update(相机对象)
基于每个level中的object和camera(摄像机)之间的距离,来设置其可见性。 为了使得多细节层次能够被自动地更新,这个方法需要在渲染循环中被调用。
function render() {
// 注意渲染函数render中执行lod的更新方法.update(camera)
lod.update(camera)
...
}
本文转载地址:我的个人技术博客