【Three.js】实现天空盒效果
一、前言
1. 为什么使用天空盒?
天空盒(Skybox)是 3D 场景中常见的技术,用于模拟环境的背景,如天空、星空、城市、山脉等。它能增强场景的沉浸感,同时对性能友好。
2. 目标
- 介绍如何用 Three.js 搭建天空盒。
- 手把手引导搭建过程,从基础代码到优化和自定义。
- 提供代码和资源,让读者可以快速上手。
二、环境准备
1. 安装 Three.js
首先,确保你已安装 Three.js
。
通过 npm 安装:
npm install three
或者直接通过 CDN 引入:
<script src="https://cdn.jsdelivr.net/npm/three@0.152.2/build/three.min.js"></script>
2. 创建项目文件结构
创建一个基本项目结构:
my-three-skybox/
├── index.html
├── app.js
├── textures/
│ ├── px.jpg # 正面
│ ├── nx.jpg # 背面
│ ├── py.jpg # 上面
│ ├── ny.jpg # 下面
│ ├── pz.jpg # 右面
│ ├── nz.jpg # 左面
三、搭建天空盒的核心代码
以下是实现天空盒的最小完整代码。
1. 加载六面纹理
天空盒由六张纹理图组成,分别代表正面、背面、上面、下面、左面和右面。
示例代码:
import * as THREE from 'three';
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 5);
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 加载天空盒纹理
const loader = new THREE.CubeTextureLoader();
const skyboxTexture = loader.load([
'textures/px.jpg', // 正面
'textures/nx.jpg', // 背面
'textures/py.jpg', // 上面
'textures/ny.jpg', // 下面
'textures/pz.jpg', // 右面
'textures/nz.jpg', // 左面
]);
// 设置天空盒
scene.background = skyboxTexture;
// 动画循环
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
2. 效果展示
运行代码后,你将看到六张纹理拼接形成的天空盒。
四、优化与自定义
1. 自定义天空盒大小
天空盒通常是一个虚拟的无穷远盒子。如果需要一个近距离观察的效果,可以创建一个立方体网格作为天空盒。
const skyboxGeometry = new THREE.BoxGeometry(100, 100, 100);
const skyboxMaterial = [
new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('textures/px.jpg'), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('textures/nx.jpg'), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('textures/py.jpg'), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('textures/ny.jpg'), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('textures/pz.jpg'), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load('textures/nz.jpg'), side: THREE.BackSide }),
];
const skybox = new THREE.Mesh(skyboxGeometry, skyboxMaterial);
scene.add(skybox);
2. 动态天空盒
通过改变天空盒纹理,可以实现时间变化(如白天到黑夜)的动态效果。
示例代码:
let currentSky = 0;
const skyTextures = [
['textures/day_px.jpg', 'textures/day_nx.jpg', 'textures/day_py.jpg', 'textures/day_ny.jpg', 'textures/day_pz.jpg', 'textures/day_nz.jpg'],
['textures/night_px.jpg', 'textures/night_nx.jpg', 'textures/night_py.jpg', 'textures/night_ny.jpg', 'textures/night_pz.jpg', 'textures/night_nz.jpg']
];
function changeSkybox() {
currentSky = (currentSky + 1) % skyTextures.length;
skyboxTexture.images = skyTextures[currentSky].map(path => new THREE.TextureLoader().load(path));
skyboxTexture.needsUpdate = true;
}
setInterval(changeSkybox, 5000); // 每5秒切换一次天空盒
五、注意事项
1. 纹理尺寸
- 推荐使用 1024x1024 或 2048x2048 的纹理图片,保证质量与性能的平衡。
- 纹理必须无缝拼接,否则会出现明显的接缝。
2. 性能优化
- 使用 压缩纹理(如
.ktx2
格式)减少内存占用。 - 通过降低分辨率提高性能。
六、资源推荐
1. 免费天空盒纹理网站
- Poly Haven:高质量 HDRI 和天空盒纹理。
- HDRI Haven:提供免费的 HDR 天空图片。
- Texture Haven:高清贴图资源。
2. 生成工具
- Spacescape:用于生成星空和太空场景的免费工具。