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属性即可实现无刷新切换,完全没必要逐帧更新。
具体步骤
将灯光实例设为可访问变量
把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); }监听主题变化并更新颜色
根据你的主题切换方式选择对应逻辑:- 若使用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)); });
- 若使用styled-components的状态/Context切换主题(比如React项目):
关键提示
- Three.js的
Color对象支持通过set()方法直接更新,传入十六进制字符串或者Color实例都可以,更新后会自动在下一帧渲染时生效。 - 不要重复创建DirectionalLight实例,否则会不断往场景中添加新灯光,造成性能浪费。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

