本文目录
- 前言
- 1、项目构建
- 1.1 安装依赖
- 1.2 初始化
- 1.3 项目结构
- 1.4 初始化的项目运行
- 2、加载模型
- 2.1 threejs三要素
- 2.1.1 代码解读
- 2.2 加载模型
- 2.2.1 代码解读
- 2.3 效果
前言
在数字技术的浪潮中,三维图形渲染技术以其独特的魅力,正逐步渗透到我们生活的方方面面,从电影特效的震撼呈现到游戏世界的沉浸式体验,再到虚拟现实(
VR
)与增强现实(AR
)技术的蓬勃发展,三维图形技术无疑成为了连接现实与虚拟世界的桥梁。而在这众多技术中,Three.js
作为一款轻量级、易于上手且功能强大的JavaScript 3D
库,凭借其跨平台、高性能的特点,成为了前端开发者探索三维世界的重要工具。
本系列文章《Three.js 3D
人物漫游项目(上)》,将带您深入Three.js
的奇妙世界,通过构建一个生动的3D人物漫游场景,让您亲身体验从项目构建到模型加载,再到最终效果呈现的全过程。这不仅是一次技术实践的旅程,更是一次对三维图形艺术无限可能的探索。
1、项目构建
1.1 安装依赖
我们使用vite
前端开发与构建工具,来进行构建与开发,首先我们新建一个文件夹roam3D
,进入文件夹根目录,
-
运行命令
yarn init -y
,效果如下:
-
接着再运行命令
yarn add -D vite
,效果如下:
-
接着运行命令
yarn add three
安装Three.js
:
1.2 初始化
-
index.html
:项目入口
安装完必要的依赖后,我们在项目根目录下新建index.html
并且写入如下代码进行初始化:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>3D漫游项目</title> <style> html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; } </style> </head> <body> <p>Roam 3D</p> </body> </html>
-
vite.config.js
:vite
配置入口
我们在项目根目录下新建vite.config.js
并且写入如下代码进行配置:import { defineConfig } from 'vite'; export default defineConfig({ server: { port: 8080 } });
这个配置更改运行的端口号。
-
package.json
:项目配置
我们在package.json
写入脚本运行的配置:"scripts": { "serve": "vite" },
这个是脚本运行项目运行起来。
- 模型
我们在根目录下新建文件夹models
将我们的模型放进去。
src
文件夹:存放一些逻辑代码。
我们在根目录下新建文件夹src
。
1.3 项目结构
安装完依赖以及初始化后,我们的项目结构如下:
├── index.html
├── models
│ └── roamGirl.glb
├── node_modules
│ ├── @esbuild
│ ├── @rollup
│ ├── @types
│ ├── esbuild
│ ├── fsevents
│ ├── nanoid
│ ├── picocolors
│ ├── postcss
│ ├── rollup
│ ├── source-map-js
│ ├── three
│ └── vite
├── src
├── package.json
├── vite.config.js
└── yarn.lock
1.4 初始化的项目运行
我们现在进行初始化的项目运行,是为了看看项目是否正确的搭建,在项目根目录终端运行命令:yarn serve
,可以看到如下图,说明成功:
浏览器访问http://localhost:8080/roam3D/index.html
:
说明项目已正常启动。接着我们可以着手准备下一步了。
2、加载模型
2.1 threejs三要素
我们在src
文件夹下新建init.js
写入如下代码:
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
// 场景
const scene = new THREE.Scene();
// 相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
// 渲染器
const renderer = new THREE.WebGLRenderer({
antialias: true,
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
// 加载glb模型方法
export const glbLoader = (url) => {
const loaderGLTF = new GLTFLoader();
return new Promise((resolve) => {
loaderGLTF.load(url, (glb) => {
resolve(glb);
});
});
};
export { scene, camera, renderer };
2.1.1 代码解读
- 我们将三要素独立出来一个文件,避免所有代码写在一个文件里过于冗长。这样可能会导致文件难以管理,还可能降低代码的可读性和可维护性。
- 我们使用了
Promise
,它是一种用于异步计算的对象,使得我们封装异步变得更加方便,使得代码更加简洁、易于理解和维护,避免回调地狱,更好的状态管理,提高代码的可读性和可维护性。(我们不仅要会写,还要尽量将代码写的优雅。)
2.2 加载模型
我们在index.html
中导入模型,写入代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D漫游项目</title>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<script type="module">
import * as THREE from 'three';
import {scene, camera, renderer, glbLoader} from './src/init.js';
renderer.render(scene, camera);
// 设置背景色
scene.background = new THREE.Color(0xFFFAFA);
camera.position.set(0,5,30);
// 环境光
const ambientLight = new THREE.AmbientLight(0x404040, 100); // 柔和的白光
scene.add(ambientLight);
// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 3);
directionalLight.position.set(5,5,5);
directionalLight.castShadow = true; // 光源开启阴影投射
scene.add(directionalLight);
// 加载模型
const loadModel = async () => {
const model = await glbLoader('../models/roamGirl.glb');
console.log(model);
model.scene.scale.set(8,8,8);
scene.add(model.scene);
};
loadModel();
// 动画循环渲染函数
const animate = () => {
renderer.render(scene, camera);
window.requestAnimationFrame(animate);
};
window.requestAnimationFrame(animate);
</script>
</body>
</html>
2.2.1 代码解读
- 我们在环境中设置了场景的背景色
scene.background = new THREE.Color(0xFFFAFA);
- 添加了两个光源,一个
ambientLight
环境光(不会产生阴影),一个平行光directionalLight
会产生阴影需要开启castShadow
为true
- 我们添加了动画循环渲染函数
animate
为什么后续的模型动画铺垫。- 我们使用了
es6
的async
及await
关键字,极大地简化了异步编程的复杂性和提高了代码的可读性。更好的错误处理,改进的流程控制。
2.3 效果
我们在项目根目录下运行命令yarn serve
,效果如下:
可以看到我们将我们模型加载进来了。
在学习的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。