three LOD 多细节层次

357 阅读3分钟

在 Three.js 中,LOD(Levels of Detail,细节层次)是一种通过在不同的距离展示不同分辨率的模型来优化渲染性能的技术。离相机近时展示高分辨率模型,远时展示低分辨率模型,从而减少计算量并提升性能。

LOD 有三个属性六个方法

LOD( ) 创建一个新的 LOD.

    const lod = new THREE.LOD();
    // 创建三个不同分辨率的模型
    const highDetailGeometry = new THREE.SphereGeometry(1, 32, 32);
    const mediumDetailGeometry = new THREE.SphereGeometry(1, 16, 16);
    const lowDetailGeometry = new THREE.SphereGeometry(1, 8, 8);
    const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
    // 创建三个不同细节级别的网格
    const highDetailModel = new THREE.Mesh(highDetailGeometry, material);
    const mediumDetailModel = new THREE.Mesh(mediumDetailGeometry, material);
    const lowDetailModel = new THREE.Mesh(lowDetailGeometry, material);
    // 为 LOD 添加不同的模型和对应的距离
    lod.addLevel(highDetailModel, 0);  // 近距离使用高细节模型
    lod.addLevel(mediumDetailModel, 50);  // 中距离使用中等细节模型
    lod.addLevel(lowDetailModel, 100);  // 远距离使用低细节模型
    // 将 LOD 添加到场景中
    scene.add(lod);
    // 获取并打印当前使用的 LOD 级别
    const currentLODLevel = lod.getCurrentLevel();
    console.log('当前使用的 LOD 级别索引:', currentLODLevel);// 0

属性

  • autoUpdate : Boolean 渲染器是否每帧自动更新 LOD 对象。如果设置为 false,则必须在渲染循环中自行调用 LOD.update()。默认为 true。
    const lod = new THREE.LOD();
    // 关闭自动更新
    lod.autoUpdate = false;
    // 在需要时手动更新
    lod.update(camera);
  • isLOD : Boolean 判断是LOD
  • levels : Array 一个包含有level objects(各层次物体)的数组。 每一个层级都是一个对象,具有以下两个属性: object —— 在这个层次中将要显示的Object3D。 distance —— 将显示这一细节层次的距离。 hysteresis —— 用于避免 LOD 边界闪烁的阈值,以距离的一部分表示。

方法

  • addLevel ( object : Object3D, distance : Float, hysteresis : Float ) : this object —— 在这个层次中将要显示的Object3D。 distance —— 将显示这一细节层次的距离。 hysteresis —— 用于避免 LOD 边界闪烁的阈值,以距离的一部分表示。默认 0.0。添加在一定距离和更大范围内显示的网格。通常来说,距离越远,网格中的细节就越少。
  • getCurrentLevel () : Integer 获取当前活动的 LOD 级别。作为级别数组的索引。如上示例中的getCurrentLevel,getCurrentLevel() 将返回当前相机距离下使用的模型层次索引值,通过该值你可以了解当前显示的是哪个细节层次的模型。
  • getObjectForDistance ( distance : Float ) : Object3D 获得第一个比distance大的Object3D(网格)的引用。
    // 通过给定的距离获取 LOD 对象
    const objectAtDistance = lod.getObjectForDistance(60);  // 查询距离为 60 的对象
    console.log(objectAtDistance);
  • raycast ( raycaster : Raycaster, intersects : Array ) : undefined 在一条投射出去的Ray(射线)和这个LOD之间获得交互。 Raycaster.intersectObject将会调用这个方法。
    // 创建一个 Raycaster
    const raycaster = new THREE.Raycaster();
    const mouse = new THREE.Vector2();
    // 监听鼠标点击事件
    window.addEventListener('click', (event) => {
        // 将鼠标点击位置转换为标准化设备坐标 (NDC)
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        // 根据鼠标位置更新 Raycaster
        raycaster.setFromCamera(mouse, camera);
        // 创建一个用于存储交互结果的数组
        const intersects = [];
        // 使用 Raycaster 检测与 LOD 对象的交互
        lod.raycast(raycaster, intersects);
        // 输出所有与射线相交的对象信息
        if (intersects.length > 0) {
            console.log('交互的对象:', intersects);
        }
    });
  • toJSON ( meta ) : Object 使用这个方法,为LOD对象中的每个细节层次创建一个JSON结构。
  • update ( camera : Camera ) : undefined 基于每个level中的object和camera(摄像机)之间的距离,来设置其可见性。