three XREstimatedLight XR估计光照

130 阅读3分钟

XREstimatedLight 是 WebXR API 中的一部分,用于在增强现实 (AR) 环境中估计和获取来自现实世界的光照信息。它可以让虚拟对象更自然地融入真实场景,通过与真实世界光照匹配提升渲染效果。

  • 前置条件
    • 支持 WebXR 的浏览器。
    • 使用兼容 WebXR 的设备(如 AR 头显或支持 WebXR 的移动设备)。
    • 确保启用了 WebXR 的 AR 模块和环境光照估算功能。 bash.gif

XREstimatedLight 有两个事件 一个属性

    // XREstimatedLight( renderer : WebGLRenderer, environmentEstimation : Boolean )
    // renderer: (必需)用于渲染场景的渲染器。主要用于与 WebXRManager 交互。
    // environmentEstimation: 如果 true,则使用 WebXR 来估计环境地图。
    
    let defaultEnvironment;
    // 创建一个默认的环境光,用于在未获取到 XR 光照估算时为场景提供基础光照。
    const defaultLight = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 1);
    // 设置默认光的方向,从 (0.5, 1, 0.25) 照射到场景。
    defaultLight.position.set(0.5, 1, 0.25);
    scene.add(defaultLight); // 将默认光源添加到场景中。
    // 启用 WebXR 支持。
    renderer.xr.enabled = true;
    // 创建 XREstimatedLight 实例,用于处理基于 XR 环境光估算的光照。
    const xrLight = new XREstimatedLight(renderer);
    // 当光照估算启动时触发的事件。
    xrLight.addEventListener('estimationstart', () => {
        // 将估算光添加到场景中,替换默认光。
        scene.add(xrLight);
        scene.remove(defaultLight);
        // 如果环境贴图可用,将其应用到场景的环境中。
        if (xrLight.environment) {
            scene.environment = xrLight.environment;
        }
    });
    // 当光照估算结束时触发的事件。
    xrLight.addEventListener('estimationend', () => {
        // 恢复默认光源。
        scene.add(defaultLight);
        scene.remove(xrLight);
        // 将场景的环境恢复为默认环境贴图。
        scene.environment = defaultEnvironment;
    });
    // 使用 RGBELoader 加载一个默认的 HDR 环境贴图,用于在没有 XR 环境光时设置场景的环境光。
    new RGBELoader()` `.setPath('https://raw.githubusercontent.com/mrdoob/three.js/refs/heads/master/examples/textures/equirectangular/')
        .load('royal_esplanade_1k.hdr', function (texture) {
            // 将加载的 HDR 贴图设置为环境贴图,映射方式为球形反射映射。
            texture.mapping = THREE.EquirectangularReflectionMapping;
            defaultEnvironment = texture; // 存储默认环境贴图。
            scene.environment = defaultEnvironment; // 设置场景的初始环境贴图。
        });
    // 创建一个球体几何体,用作后续金属和粗糙度演示的小球。
    const ballGeometry = new THREE.SphereGeometry(0.175, 32, 32);
    // 创建一个组来存放小球。
    const ballGroup = new THREE.Group();
    // 将小球组放置在场景中的位置,距离摄像机较远。
    ballGroup.position.z = -2;
    // 定义行和列的数量,用于小球的排列。
    const rows = 3;
    const cols = 3;
    // 遍历行和列,生成不同材质的小球。
    for (let i = 0; i < rows; i++) {
        for (let j = 0; j < cols; j++) {
            // 创建一个基于标准材质的球体材质。
            // `roughness` 代表材质的粗糙度,值为 i / rows。
            // `metalness` 代表材质的金属度,值为 j / cols。
            const ballMaterial = new THREE.MeshStandardMaterial({
                color: 0xdddddd, // 灰色基底颜色。
                roughness: i / rows, // 根据行数调整粗糙度。
                metalness: j / cols, // 根据列数调整金属度。
            });
            // 创建一个球体网格,将几何体与材质结合。
            const ballMesh = new THREE.Mesh(ballGeometry, ballMaterial);
            // 设置小球的位置,根据行列的索引排列。
            ballMesh.position.set(
                (i + 0.5 - rows * 0.5) * 0.4, // X 坐标:根据列的数量居中排列。
                (j + 0.5 - cols * 0.5) * 0.4, // Y 坐标:根据行的数量居中排列。
                0 // Z 坐标保持为 0。
            );
            // 将小球添加到小球组中。
            ballGroup.add(ballMesh);
        }
    }
    // 将小球组添加到场景中。
    scene.add(ballGroup);

事件

  • estimationstart 当估计的照明值开始更新时触发。
  • estimationend 当估计的照明值停止更新时触发。

属性

  • environment : Texture WebXR 估计的环境地图。仅当 environmentEstimation 为 时,此选项才可用 true。 它可以用作 Scene.environment 的 MeshStandardMaterial.envMap 或 Scene.background。