Three.js 多细节层次 LOD

发布于 2021-07-13 21:24:02 字数 4433 浏览 1756 评论 0

开发 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)
...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

虐人心

有一天你能到我的心里去,你会看到那里全是你给的伤悲。

0 文章
0 评论
24515 人气
更多

推荐作者

qq_aHcEbj

文章 0 评论 0

寄与心

文章 0 评论 0

13545243122

文章 0 评论 0

流星番茄

文章 0 评论 0

春庭雪

文章 0 评论 0

潮男不是我

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文