1. Sky 组件简介
Sky
组件是 Three.js 提供的一个用于渲染物理天空的工具。它基于大气散射模型,模拟真实世界中的瑞利散射(Rayleigh Scattering)和米氏散射(Mie Scattering),从而生成逼真的天空效果。
Sky
组件主要用于:
- 模拟自然天空(晴天、黄昏、雾霾等)
- 动态调整太阳位置(实现日出日落效果)
- 生成环境贴图(影响全局光照)
2. Sky 组件的使用
2.1 创建 Sky
const sky = new Sky(); // 创建 Sky 实例
sky.scale.set(100, 100, 100); // 设置天空的大小
scene.add(sky); // 添加到场景
scale
影响天空盒的大小,通常设为100
以上,确保填充整个视野。
2.2 调整 Sky 的 Uniform 参数
sky.material.uniforms['turbidity'].value = 10; // 影响空气浑浊度
sky.material.uniforms['rayleigh'].value = 3; // 影响瑞利散射,决定天空颜色
sky.material.uniforms['mieCoefficient'].value = 0.1; // 控制雾霾效果
sky.material.uniforms['mieDirectionalG'].value = 0.95; // 控制光晕强度
sky.material.uniforms['sunPosition'].value.set(0.3, -0.038, -0.95); // 太阳位置
uniforms
是Sky
组件的 GLSL 着色器参数,可以调整天空的光学特性。
3. Sky 组件的关键参数
3.1 瑞利散射(Rayleigh Scattering)
- 控制蓝天的颜色,数值越大,天空越蓝。
- 物理现象:短波蓝光更容易被散射,所以白天天空是蓝色的。
- 典型值:
sky.material.uniforms['rayleigh'].value = 3; // 晴天 sky.material.uniforms['rayleigh'].value = 0.5; // 暮色
3.2 米氏散射(Mie Scattering)
- 控制空气中悬浮颗粒对光的散射,影响雾霾和太阳光晕的效果。
mieCoefficient
控制散射强度,mieDirectionalG
控制方向性。- 物理现象:大颗粒悬浮物(如雾、烟)散射光线,导致太阳周围出现光晕。
- 典型值:
sky.material.uniforms['mieCoefficient'].value = 0.005; // 晴天 sky.material.uniforms['mieCoefficient'].value = 0.1; // 雾霾天气 sky.material.uniforms['mieDirectionalG'].value = 0.8; // 标准太阳光晕
3.3 空气浑浊度(Turbidity)
- 控制空气污染程度,值越大,天空越灰暗。
- 物理现象:空气中的水蒸气和污染物吸收光线,降低能见度。
- 典型值:
sky.material.uniforms['turbidity'].value = 2; // 清澈蓝天 sky.material.uniforms['turbidity'].value = 10; // 轻度雾霾 sky.material.uniforms['turbidity'].value = 20; // 严重雾霾
3.4 太阳位置(Sun Position)
- 控制太阳的方向,影响光照和阴影角度。
- 物理现象:太阳越低,光线穿过大气层的距离越长,导致更多红光散射,形成黄昏颜色。
- 典型值:
sky.material.uniforms['sunPosition'].value.set(0, 1, 0); // 中午 sky.material.uniforms['sunPosition'].value.set(-1, 0.1, -1); // 夕阳
4. Sky 组件的应用
4.1 模拟不同天气
天气 | turbidity | rayleigh | mieCoefficient | mieDirectionalG |
---|---|---|---|---|
晴天 | 2 | 3 | 0.005 | 0.8 |
阴天 | 5 | 2 | 0.02 | 0.9 |
黄昏 | 10 | 2 | 0.08 | 0.9 |
雾霾 | 20 | 1 | 0.1 | 1 |
4.2 让太阳动态移动
const sun = new THREE.Vector3();
function updateSun(time) {
sun.set(Math.sin(time) * 10, Math.cos(time) * 5, -5);
sky.material.uniforms['sunPosition'].value.copy(sun);
}
function animate() {
const elapsedTime = clock.getElapsedTime();
updateSun(elapsedTime * 0.1);
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
animate();
这样,太阳会随时间变化,模拟日出日落。
4.3 生成环境贴图
结合 PMREMGenerator
让天空影响场景光照:
const pmremGenerator = new THREE.PMREMGenerator(renderer);
const skybox = pmremGenerator.fromScene(sky);
scene.environment = skybox.texture;
5. 可能遇到的问题
5.1 uniforms
访问报错
- 确保
Sky
已成功添加到scene
,否则material
可能未初始化:console.log(sky.material.uniforms); // 检查 uniforms 是否可用
5.2 天空颜色异常
rayleigh
过低:导致天空变灰。turbidity
过高:导致雾霾太浓。mieCoefficient
过高:导致太阳光晕异常大。
5.3 太阳位置无效
- 太阳位置需要同时更新光源:
directionalLight.position.copy(sky.material.uniforms['sunPosition'].value);
6. 总结
Sky
组件用于模拟物理天空,基于瑞利散射和米氏散射模型。- 关键参数:
turbidity
控制空气浑浊度(污染/雾霾)。rayleigh
控制瑞利散射(天空颜色)。mieCoefficient
控制米氏散射(光晕/雾霾)。sunPosition
控制太阳角度(影响阴影和光照)。
- 通过调整参数,可以模拟晴天、阴天、黄昏、雾霾等不同天气。
- 可以让
sunPosition
动态变化,实现日出日落效果。 - 可以结合
PMREMGenerator
生成环境贴图,让天空影响全局光照。
这样,你可以用 Three.js 轻松构建逼真的物理天空环境 🚀