当前位置: 首页 > article >正文

【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:用于生成星空和太空场景的免费工具。


http://www.kler.cn/a/401052.html

相关文章:

  • 51单片机基础01 单片机最小系统
  • 数据分析24.11.13
  • 网页作业9
  • 【AI+教育】一些记录@2024.11.11
  • Ajax的相关内容
  • Visual Studio 圈复杂度评估
  • Django模型关系之一对一
  • 设计模式之插件模式
  • Android WMS概览
  • 基于Java Springboot编程语言在线学习平台
  • 鸿蒙动画开发07——粒子动画
  • 小程序-基于java+SpringBoot+Vue的经济新闻资讯设计与实现
  • 怀旧游戏打卡清单(TODO)
  • java 根据 pdf 模板带图片文字生成pdf文件
  • 在阿里云快速启动Appsmith搭建前端页面
  • Windows注册表基础学习
  • C# 深层副本与浅层副本 深拷贝与浅拷贝
  • Pytest-Bdd-Playwright 系列教程(11):场景快捷方式
  • 【Rust调用Windows API】读取进程启动时间、退出时间、CPU利用率
  • 【QNX】QNX侧如何抓取日志?
  • 9.1 使用haarcascade_frontalface_default.xml分类器对静态图像进行人脸检测。
  • 【项目组件】第三方库——MySQL CAPI
  • 在ubuntu下将virtualbox虚拟机的磁盘重设大小的方法
  • [element-ui]根据 el-table的某一列值大小设置该列背景颜色宽度
  • 细说STM32单片机DMA中断收发RTC实时时间并改善其鲁棒性的方法
  • 《Python网络安全项目实战》项目6 编写密码工具程序_练习题(1)