【Three.js】知识梳理十九:线性雾(Fog)、指数雾(FogExp2)和范围雾(RangeFog)

742 阅读3分钟

雾是3D图形中创建深度和氛围的重要工具。Three.js提供了多种类型的雾:线性雾(THREE.Fog),指数雾(THREE.FogExp2)和范围雾(RangeFog)。本文将探讨这三种类型的雾,通过代码示例进行的实践应用。

雾模拟了大气的效果,使远处的物体看起来更模糊。它有助于创建深度感,并能增强场景的氛围。在Three.js中,只需几行代码即可轻松添加雾效果。

1.线性雾(THREE.Fog)

线性雾从起始距离到终止距离线性地淡化。它由三个主要参数定义:颜色、近处和远处。

属性

  • color(颜色) : 雾的颜色。
  • near(近处) : 雾开始的距离。
  • far(远处) : 雾结束的距离。

示例代码

// 创建一个场景
const scene = new THREE.Scene();
​
// 向场景中添加线性雾
const color = 0xffffff; // 白色雾
const near = 10;
const far = 50;
scene.fog = new THREE.Fog(color, near, far);
​
// 向场景中添加物体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
for (let i = 0; i < 100; i++) {
  const cube = new THREE.Mesh(geometry, material);
  cube.position.set(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50);
  scene.add(cube);
}
​
// 创建一个相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 30;
​
// 创建一个渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
​
// 渲染场景
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

官方案例:three.js examples (threejs.org)

image.png

2.指数雾(THREE.FogExp2)

指数雾通过距离指数增加雾的密度,提供了更为真实的雾效果。

属性

  • color(颜色) : 雾的颜色。
  • density(密度) : 雾的密度。

示例代码:

// 创建一个场景
const scene = new THREE.Scene();
​
// 向场景中添加指数雾
const color = 0xffffff; // 白色雾
const density = 0.01;
scene.fog = new THREE.FogExp2(color, density);
​
// 向场景中添加物体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
for (let i = 0; i < 100; i++) {
  const cube = new THREE.Mesh(geometry, material);
  cube.position.set(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50);
  scene.add(cube);
}
​
// 创建一个相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 30;
​
// 创建一个渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
​
// 渲染场景
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

官方案例: three.js examples (threejs.org)

image.png

3.范围雾(RangeFog)

范围雾根据距离在一定范围内增加雾的密度,超出范围后雾的密度不再变化。

属性

  • color(颜色) : 雾的颜色。
  • near(近处) : 雾开始的距离。
  • far(远处) : 雾结束的距离。
  • density(密度) : 雾的密度。

示例代码:

// 创建一个场景
const scene = new THREE.Scene();

// 向场景中添加范围雾
const color = 0xffffff; // 白色雾
const near = 10;
const far = 50;
const density = 0.02;
scene.fog = new RangeFog(color, near, far, density);

// 向场景中添加物体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
for (let i = 0; i < 100; i++) {
  const cube = new THREE.Mesh(geometry, material);
  cube.position.set(Math.random() * 100 - 50, Math.random() * 100 - 50, Math.random() * 100 - 50);
  scene.add(cube);
}

// 创建一个相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 30;

// 创建一个渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 渲染场景
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

官方案例:three.js examples (threejs.org)

image.png

4.线性雾,指数雾和范围雾的比较

  • 线性雾: 提供了一个简单且可预测的雾效果,从指定的距离开始并结束。
  • 指数雾: 提供了更自然的雾效果,雾的密度随着距离的增加而指数增加,使其更适合于现实场景。
  • 范围雾: 在一定范围内增加雾的密度,超出范围后雾的密度不再变化,适用于需要特定范围内雾效果的场景。

image.png

5.实际应用

  • 增强深度: 三种类型的雾都可以增强场景中的深度感,使其看起来更具沉浸感。
  • 大气效果: 使用雾来创建如薄雾、烟霾或污染等大气效果。
  • 引导观众: 通过战略性地放置雾,可以引导观众的注意力到场景的特定部分。

雾是Three.js中一个强大的工具,可以显著提升3D场景的视觉效果。无论你选择线性雾的简单性、指数雾的真实性还是范围雾的特定范围效果,理解如何实现和操作雾效果可以帮助你创建更具吸引力和沉浸感的体验。