You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用lil-gui修改Three.js灯光颜色?问题排查与修复

问题排查与修复方案

常见问题原因

  1. 颜色不生效

    • 误用了不支持光照的材质(比如MeshBasicMaterial),这类材质不受光源影响,自然看不到反射光变化;
    • 修改光源颜色后未触发材质更新,Three.js不会自动感知颜色属性变化,需要手动标记材质需重新计算;
    • 错误修改了球体自身颜色,而非反射光(环境光/方向光等)的颜色。
  2. 浏览器卡顿

    • 拖动滑块时重复执行场景、光源或球体的初始化逻辑,导致内存堆积;
    • lil-gui回调函数里冗余调用渲染循环启动逻辑,每次拖动都重复创建渲染请求,造成性能浪费。

修复后的完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Three.js Reflect Light Color Control</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="https://cdn.jsdelivr.net/npm/three@0.158.0/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/lil-gui@0.18.2/dist/lil-gui.umd.min.js"></script>
    <script>
        // 基础场景资源只初始化一次
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 使用支持光照的PBR材质
        const geometry = new THREE.SphereGeometry(1, 32, 32);
        const material = new THREE.MeshStandardMaterial({ color: 0xffffff });
        const sphere = new THREE.Mesh(geometry, material);
        scene.add(sphere);

        // 配置反射光(环境光+方向光)
        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        scene.add(ambientLight);
        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        directionalLight.position.set(5, 5, 5);
        scene.add(directionalLight);

        camera.position.z = 5;

        // 渲染循环只启动一次
        function animate() {
            requestAnimationFrame(animate);
            renderer.render(scene, camera);
        }
        animate();

        // lil-gui控制器:仅修改光源颜色,无冗余操作
        const gui = new lil.GUI();
        const lightConfig = {
            ambientColor: '#ffffff',
            directionalColor: '#ffffff'
        };

        gui.addColor(lightConfig, 'ambientColor')
            .name('环境反射光')
            .onChange((hex) => {
                ambientLight.color.set(hex);
                material.needsUpdate = true; // 强制材质更新
            });

        gui.addColor(lightConfig, 'directionalColor')
            .name('直射反射光')
            .onChange((hex) => {
                directionalLight.color.set(hex);
                material.needsUpdate = true;
            });

        // 窗口自适应逻辑
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>

关键修改点说明

  • 材质替换:用MeshStandardMaterial替代无光照支持的材质,确保球体能正确响应光源颜色变化;
  • 资源复用:场景、相机、光源、球体等核心资源只初始化一次,避免滑块拖动时重复创建导致内存泄漏;
  • 手动触发更新:修改光源颜色后设置material.needsUpdate = true,通知Three.js重新计算材质渲染参数;
  • 回调优化:lil-gui的回调仅修改对应光源的颜色属性,无冗余的初始化或渲染逻辑;
  • 独立渲染循环:渲染循环仅启动一次,不会因滑块操作重复触发,避免性能浪费。

内容的提问来源于stack exchange,提问作者Cambria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:45:39