在 Three.js 中,天空是创造逼真世界的重要组成部分之一。Three.js 提供了一个名为 Sky 的类,可以帮助开发者轻松地实现各种壮丽的天空效果。无论是日出时分的柔和晨曦,还是星空下的宁静夜晚,Sky 类都能帮助你实现恰到好处的背景效果。

Sky 类的基本用法
在 Three.js 中,使用 Sky 类创建天空背景通常包括以下几个步骤:
import { Sky } from "three/examples/jsm/objects/Sky.js";
import * as THREE from "three";
// 创建天空的立方体贴图
const sky = new Sky();
// 设置天空的参数,比如太阳的位置、云的数量等
const parameters = {
turbidity: 5,
rayleigh: 2,
mieCoefficient: 0.005,
mieDirectionalG: 0.8,
sunPosition: new Vector3(0, 1, 0), // 设置太阳位置在正上方
up: new Vector3(0, 1, 0),
};
const skyUniforms = sky.material.uniforms;
skyUniforms["turbidity"].value = parameters.turbidity;
skyUniforms["rayleigh"].value = parameters.rayleigh;
skyUniforms["mieCoefficient"].value = parameters.mieCoefficient;
skyUniforms["mieDirectionalG"].value = parameters.mieDirectionalG;
// 创建一个天空盒并添加到场景中
const skyBox = new THREE.Mesh(new THREE.BoxGeometry(100000, 100000, 100000), sky.material);
scene.add(skyBox);参数详细说明
turbidity: 控制空气湍流度,影响天空的清晰度和颜色。通常在 2 到 10 之间调整,数值越高表示越清晰的天空。rayleigh: 控制雷利散射,影响天空中的蓝天颜色和光线散射效果。mieCoefficient: 控制米氏散射系数,影响天空中非蓝色光线的散射强度。mieDirectionalG: 控制米氏散射的方向性因子,影响散射光线的分布方向。sunPosition: 太阳位置向量,影响天空中太阳光的角度和强度。up: 天空的上方向向量,默认为(0, 1, 0),通常用于确定天空的方向。
自定义天空效果
当使用 Three.js 中的 Sky 类来自定义天空效果时,可以根据不同的参数设置实现多样化的场景。以下是三个不同的天空场景示例:
感谢提供源码!基于这个 Sky 类的源码,我们可以根据不同的场景需求来设置 uniforms 的值,以创建不同的天空效果。以下是三个不同的天空场景示例,根据你提供的参数进行调整:
1. 清晨的日出
const parameters = {
turbidity: 10,
rayleigh: 3,
mieCoefficient: 0.005,
mieDirectionalG: 0.8,
};
2. 傍晚黄昏
const parameters = {
turbidity: 8,
rayleigh: 3,
mieCoefficient: 0.001,
mieDirectionalG: 0.6,
sunPosition: new Vector3(0, 0, -1), // 太阳设置在地平线以下
};这个设置适合模拟星空下的夜晚,将 sunPosition 设置在地平线以下,从而隐藏太阳,并调整其他参数以使天空显得暗淡,增强星星的亮度效果。
官网的案例不是直接设置的 sunPosition,他是通过
const phi = THREE.MathUtils.degToRad(90 - effectController.elevation);
const theta = THREE.MathUtils.degToRad(effectController.azimuth);
sun.setFromSphericalCoords(1, phi, theta);
uniforms["sunPosition"].value.copy(sun);- phi 和 theta 的计算:
phi和theta是用来描述太阳在球坐标系中的位置的角度。phi表示仰角,通过90 - effectController.elevation计算得到。effectController.elevation控制着太阳的高度角度,通常是从地平线往上看的角度。theta表示方位角,由effectController.azimuth控制。它是从参考方向(通常是东方)顺时针或逆时针旋转的角度。
- 设置太阳位置:
sun.setFromSphericalCoords( 1, phi, theta ):这个方法将球坐标转换为直角坐标,以便描述太阳在三维空间中的位置。1是半径,这里表示球的半径为 1,实际上是个单位向量。phi和theta是之前计算得到的仰角和方位角。
- 应用太阳位置到着色器:
uniforms['sunPosition'].value.copy( sun ):这里将计算得到的太阳位置sun复制到天空盒子的材质(着色器)的sunPositionuniform 变量中。- 这样一来,天空盒子的着色器就可以根据
sunPosition变量来调整光照和阴影,使得整个场景的光线和阴影效果更加生动和真实。
所以我们通过设置elevation = 0 ,就可以将太阳显示的位置靠下了。

参考
https://threejs.org/examples/#webgl_shaders_sky (opens in a new tab)