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

Three.js实现平行光颜色的实时动态更新(逐帧更新)

实时切换Three.js平行光颜色的解决方案

问题描述

我希望根据网页的亮色模式或暗色主题切换DirectionalLight(平行光)的颜色,当前实现虽能生效,但需刷新页面才能看到变化。以下是我的代码:从styled-components的JSON中读取十六进制颜色,将其转换为Three.js颜色格式(如0xffffff)来创建平行光。

var directionalLight = new THREE.DirectionalLight(
      new THREE.Color(theme.background),
      0.6
    );
    directionalLight.position.set(-10, 10, 5);
    directionalLight.castShadow = true;
    directionalLight.shadow.bias = -0.0005;
    scene.add(directionalLight);

请问是否有办法逐帧更新灯光颜色以实现实时可见的变化?

解决方案

核心思路

不用重新创建灯光实例,直接复用已有的DirectionalLight,监听主题变化事件实时更新它的color属性即可实现无刷新切换,完全没必要逐帧更新。

具体步骤

  1. 将灯光实例设为可访问变量
    把directionalLight定义在主题切换代码能触达的作用域里,比如组件状态或全局模块:

    // 全局或组件内可访问的变量
    let directionalLight;
    
    // 初始化场景时创建灯光
    function initScene() {
      directionalLight = new THREE.DirectionalLight(
        new THREE.Color(theme.background),
        0.6
      );
      directionalLight.position.set(-10, 10, 5);
      directionalLight.castShadow = true;
      directionalLight.shadow.bias = -0.0005;
      scene.add(directionalLight);
    }
    
  2. 监听主题变化并更新颜色
    根据你的主题切换方式选择对应逻辑:

    • 若使用styled-components的状态/Context切换主题(比如React项目):
      // 以React为例,监听theme变化
      useEffect(() => {
        // 直接更新现有灯光的颜色
        directionalLight.color.set(new THREE.Color(theme.background));
      }, [theme]);
      
    • 若监听系统深色/浅色模式切换:
      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
        const targetTheme = e.matches ? darkTheme : lightTheme;
        directionalLight.color.set(new THREE.Color(targetTheme.background));
      });
      

关键提示

  • Three.js的Color对象支持通过set()方法直接更新,传入十六进制字符串或者Color实例都可以,更新后会自动在下一帧渲染时生效。
  • 不要重复创建DirectionalLight实例,否则会不断往场景中添加新灯光,造成性能浪费。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:59:15