第 60 期 - Three.js 入门开发全解析
logoFRONTALK AI/12月22日 16:31/阅读原文

摘要

文章从 Three.js 的介绍开始,讲述开发环境搭建,涵盖重要概念如场景、物体、相机、渲染器等,接着展示第一个场景的创建过程、坐标系统相关知识、物体移动方法,还包括几何体与材质创建物体、动画制作、交互添加、光源种类及环境光阴影效果实现,最后介绍了纹理添加到平面和立方体上

Three.js 介绍

Three.js 是一个开源的应用级 3D JavaScript 库,可让开发者在网页创建 3D 体验,它屏蔽了 WebGL 底层调用细节。

开发环境搭建

  1. 初始化项目:创建目录后使用npm init -y初始化package.json
  2. 安装打包工具:例如使用npm install --save-dev parcel安装 Web 应用打包工具 parcel(也可使用其他如 webpack 等)。
  3. 创建文件:新建src/index.htmlsrc/script.js两个文件。
    • index.html中设置了基本的网页结构,并且<script>标签引入script.js时需加上type="module",因为script.js会使用import模块化语法。
    • package.json中加入"start": "parcel src/index.html"脚本。
  4. 引入 Three.js:使用npm install three引入 Three.js,在src/script.js中可通过import * as THREE from "three";console.log(THREE);验证是否引入成功。

Three.js 重要概念

  1. scene(场景):像容器,可加入物体(模型、粒子、光源、相机等)。
  2. objects(物体):种类多样,如原始几何体、导入模型、粒子、光源等。
  3. camera(相机):理论视角,虽然加入场景但不可见,有透视相机等类型。
    • 透视相机构造参数有视野(fov)、宽高比(aspect)、近平面距离(near)、远平面距离(far)。
  4. renderer(渲染器):从相机角度渲染场景,结果绘制到canvas中。

第一个 Three.js 场景

  1. 创建渲染器并设置尺寸添加到body中:
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.pixelRatio = window.devicePixelRatio;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.append(renderer.domElement);
  1. 创建场景:
const scene = new THREE.Scene();
  1. 创建相机并设置参数:
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
  1. 创建物体(坐标辅助线)并添加到场景:
const axis = new THREE.AxesHelper(5);
scene.add(axis);
  1. 渲染场景:
renderer.render(scene, camera);

但初始时屏幕黑暗,原因与坐标系统有关。

坐标系统

Three.js 使用右手坐标系,默认物体和透视相机在原点(0,0,0),距离为0且相机看向原点,所以不渲染内容。解决办法是移动相机或物体,如设置camera.position.set(5, 5, 10);或单独设置坐标,且设置camera.lookAt(0, 0, 0);就能看到坐标辅助线。

Geometry 和 Material

创建立方体需要创建Mesh对象(几何形状和材质的组合)。

  1. 创建立方几何体:
const geometry = new THREE.BoxGeometry(4, 4, 4);
  1. 创建红色材质:
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
  1. 组合为Mesh对象并添加到场景:
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

立方体动画

  1. 设置初始旋转角度:
cube.rotation.y = Math.PI / 4;
  1. 通过requestAnimationFrame实现动画:
function animate() {
  requestAnimationFrame(animate);
  cube.rotation.y += 0.01;
  renderer.render(scene, camera);
}
animate();
  1. 动画优化:使用three.js中内置的Clock保证两秒自转一圈。
const clock = new THREE.Clock();
function animate() {
  requestAnimationFrame(animate);
  const elapsedTime = clock.getElapsedTime();
  cube.rotation.y = elapsedTime * Math.PI;
  renderer.render(scene, camera);
}

添加交互

添加OrbitControls控制器实现用户与场景交互。

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
const controls = new OrbitControls(camera, renderer.domElement);
controls.update();

交互添加光源

Three.js 中有环境光源、方向光源和点光源三种重要光源。

  1. 环境光(Ambient Light):均匀照亮场景所有物体,不考虑位置和方向。
  2. 方向光(Directional Light):平行光源,有确定方向和强度,类似太阳光。
  3. 点光源(Point Light):位于特定位置,向所有方向发射光线,类似灯泡。 添加环境光和方向光示例:
const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(10, 0, 10);
scene.add(directionalLight);

环境光阴影

  1. 使渲染器能渲染阴影:
renderer.shadowMap.enabled = true;
  1. 方向光投射阴影:
directionalLight.castShadow = true;
  1. 立方体会产生阴影:
cube.castShadow = true;
  1. 创建能接受阴影的平面并设置:
const planeGeometry = new THREE.PlaneGeometry(20, 20);
const planeMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff });
const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotation.x = -0.5 * Math.PI;
planeMesh.position.set(0, -3, 0);
planeMesh.receiveShadow = true;
scene.add(planeMesh);
  1. 添加方向光辅助线:
const directionalLightHelper = new THREE.DirectionalLightHelper(
  directionalLight
);
scene.add(directionalLightHelper);

纹理

  1. 地板纹理
    • 引入图片。
    • 初始化纹理加载器。
    • 给地板加载纹理。
import floor from "./images/floor_wood.jpeg";
const textloader = new THREE.TextureLoader();
const planeMaterial = new THREE.MeshStandardMaterial({
  map: textloader.load(floor),
});
  1. 立方体纹理:为不同面设置不同纹理,通过在构造Mesh对象时传入6MeshBasicMaterial对象的数组,按特定顺序设置各面纹理。
 

扩展阅读

Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有