在 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
复制到天空盒子的材质(着色器)的sunPosition
uniform 变量中。- 这样一来,天空盒子的着色器就可以根据
sunPosition
变量来调整光照和阴影,使得整个场景的光线和阴影效果更加生动和真实。
所以我们通过设置elevation
= 0 ,就可以将太阳显示的位置靠下了。
参考
https://threejs.org/examples/#webgl_shaders_sky (opens in a new tab)