Three.js案例
Three.js 中的 Sky 类:创建逼真的天空

在 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 的计算
    • phitheta 是用来描述太阳在球坐标系中的位置的角度。
    • phi 表示仰角,通过 90 - effectController.elevation 计算得到。effectController.elevation 控制着太阳的高度角度,通常是从地平线往上看的角度。
    • theta 表示方位角,由 effectController.azimuth 控制。它是从参考方向(通常是东方)顺时针或逆时针旋转的角度。
  • 设置太阳位置
    • sun.setFromSphericalCoords( 1, phi, theta ):这个方法将球坐标转换为直角坐标,以便描述太阳在三维空间中的位置。
      • 1 是半径,这里表示球的半径为 1,实际上是个单位向量。
      • phitheta 是之前计算得到的仰角和方位角。
  • 应用太阳位置到着色器
    • uniforms['sunPosition'].value.copy( sun ):这里将计算得到的太阳位置 sun 复制到天空盒子的材质(着色器)的 sunPosition uniform 变量中。
    • 这样一来,天空盒子的着色器就可以根据 sunPosition 变量来调整光照和阴影,使得整个场景的光线和阴影效果更加生动和真实。

所以我们通过设置elevation = 0 ,就可以将太阳显示的位置靠下了。

参考

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