three.js 零基础到入门

发布于:2025-06-09 ⋅ 阅读:(23) ⋅ 点赞:(0)

three.js 零基础到入门

    • 什么是 three.js
    • 为什么使用 three.js
    • 使用 Three.js
      • 1. 创建场景
        • 示例
      • 2.创建相机
      • 3. 创建立方体并添加网格地面
        • 示例
      • 5. 创建渲染器
        • 示例
      • 6. 添加效果(移动/雾/相机跟随物体/背景)
        • 自动旋转
          • 示例
          • 效果
      • 相机自动旋转
          • 示例
        • 展示效果
      • 实现由远到近的雾
        • 示例
        • 展示效果
      • Three.js 环境贴图应用
        • 示例
        • 展示效果
      • 实现物体反光和阴影(点光源,环境光源)
        • 光源
      • 接受光源/投射效果(阴影)
        • 示例
        • 效果
      • 7. 总结练习
        • 控制移动思想
        • 示例
        • 效果
      • 8. 总结知识点

什么是 three.js

Three.js 是一个用于在网页上创建和展示 3D 图形的 JavaScript 库。它简化了 WebGL 的复杂性,为开发者提供了一组易于使用的 API,使得创建、显示和操控 3D 对象变得更加方便。以下是对 Three.js 的更详细解释:

为什么使用 three.js

解决了在前端开发中实现 3d 效果的繁琐问题

  • 封装 WebGL:WebGL 是一个用于在浏览器内呈现 3D 图形的低级 API,它提供了强大的功能,但学习曲线陡峭。Three.js 封装了 WebGL 的许多复杂性,提供了更简单的接口。
  • 易于使用的 API:开发者可以使用简单的函数和对象来创建和操控 3D 场景,而不需要深入理解 WebGL 的细节。
  • 快速原型:由于其易用性,开发者能够快速创建和测试 3D 原型,缩短了开发周期。

使用 Three.js

1. 创建场景

Three.js 中,Scene 类是构建 3D 环境的基础组件。它充当所有 3D 对象(例立方体、球体、灯光、相机等)的容器,并管理这些对象的渲染。

示例
const scene = new THREE.Scene();

2.创建相机

  • Three.js 中,PerspectiveCamera 类用于创建透视相机,它能够模拟人眼的视角,让场景中的物体在视觉上具有深度感。透视相机是 3D 图形中常用的一种相机类型,尤其适用于展示真实世界中的场景。
  • 在 Three.js 的所有类中,position 属性用于修改物体在三维空间中的坐标。通过设置 position,我们可以控制相机或其他对象在 X、Y 和 Z 轴上的位置。这使得我们能够灵活地决定视角和观察点,进而影响最终的渲染效果。通过调整相机的位置,我们可以改变观察者的视角,以便获得不同的视觉体验。

示例

const camera = new THREE.PerspectiveCamera();
camera.position.z = 10;
camera.position.y = 2;

3. 创建立方体并添加网格地面

  • BoxGeometryThree.js 中用于创建立方体的一个类。构造函数接受三个参数,分别表示立方体的宽度、高度和深度。
  • MeshBasicMaterial 是一种材质类型,它用于定义 3D 对象的外观。与其他材质不同,MeshBasicMaterial不受光照影响,因此它总是以定义的颜色显示,无论场景中的光照条件如何。
  • MeshThree.js 中用于创建网格的一个类。Mesh 对象结合了几何体(如 BoxGeometry)和材质(如 MeshBasicMaterial)来构建可视的 3D 物体。通过将几何体和材质结合,Mesh 表示一个具有具体形状和视觉外观的三维对象,可以在场景中进行操作和渲染。
示例
//创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1);
//设置立方体的颜色
const material = new THREE.MeshBasicMaterial({ color: 0x888 });
//创建网格并把立方体放进去
const cube = new THREE.Mesh(geometry, material);
//设置立方体的位置在可视范围内
cube.position.set(0, 3, 0);
//添加网格地面
const gridHelper = new THREE.GridHelper(10, 10);
//把立方体和网格地面加入场景中
scene.add(cube);
scene.add(gridHelper);

提示
GridHelperThree.js 提供的一个辅助类,用于在场景中生成一个可视化的网格。它的主要功能是帮助开发者和设计师在 3D 空间中定位和对齐对象。GridHelper 的网格通常由线条构成,便于快速判断场景的坐标和对象的位置。

数字代表的含义:

  • 第一个参数定义了网格的边长,即网格范围的大小。
  • 第二个参数决定了每个维度上将网格细分为多少个单元,影响网格的密度和视觉清晰度。

5. 创建渲染器

Three.js 中,WebGLRenderer 是主要的渲染器,它利用 WebGL 技术来在浏览器中绘制高效的 3D 图形。

示例
const renderer = new THEE.WebGLRenderer();
//渲染到id名为container的容器里面
document.getElemnetById("container").appendChild(renderer.domElement);
//调整窗口的大小
renderer.setSize(window.innerWidth, window.innerHeight);
//刚才创建的场景和立方体放进来
renderer.render(scene, camera);

6. 添加效果(移动/雾/相机跟随物体/背景)

自动旋转
  • 让立方体自动旋转,可以通过调整 Mesh 对象的 rotation 属性来实现。在 onMounted 中定义一个名为 animate 的函数,该函数内使用 requestAnimationFrame(animate) 实现持续的动画循环,并在每帧中更新
示例
const animate = () => {
  requestAnimationFrame(animate);
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  //重新放进来
  renderer.render(scene, camera);
};

animate();
效果

Alt

相机自动旋转

  • 为了实现相机的自动旋转,可以使用 OrbitControls 类。该类提供了 autoRotate 属性,启用此属性后,相机将自动旋转。此外,可以通过 autoRotateSpeed 属性设置旋转的速度,以控制相机自转的快慢。
示例
const controls = new OrbitControls(camera, renderer.domElement);
// 对轨道控制器改变时候进行监听
controls.addEventListener("change", function () {
  console.log("触发change");
});

// 添加阻尼
controls.enableDamping = true;
controls.dampingFactor = 0.01;

// 自动旋转
controls.autoRotate = true;
controls.autoRotateSpeed = 0.5;

// 进行渲染
// renderer.render(scene, camera);

// 让立方体动起来
function animate() {
  // 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
  requestAnimationFrame(animate);
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  // 轨道控制器更新
  controls.update();
  renderer.render(scene, camera);
}
animate();
展示效果

Alt

实现由远到近的雾

  • 为了实现 场景由远到近的雾 可以使用 Three.js 中的 Fog 类来添加
示例
scene.fog = new THREE.Fog(0xcccccc, 10, 15);
展示效果

Three.js 环境贴图应用

  • 使用THREE.CubeTextureLoader加载 6 面环境贴图
  • 同时应用于场景背景和球体材质
  • 实现全景天空盒+环境反射效果
示例
/**
 * 立方体贴图加载
 * 图片顺序:右(x+)、左(x-)、上(y+)、下(y-)、后(z+)、前(z-)
 * 注意:路径需要替换为实际资源目录
 */
const cubleTExture = new THREE.CubeTextureLoader()
  .setPath("/") // 纹理资源目录路径
  .load([
    "04.jpg",
    "01.jpg", // 右/左
    "05.jpg",
    "02.jpg", // 上/下
    "06.jpg",
    "03.jpg", // 后/前
  ]);

// 将立方体贴图设置为场景背景(全景天空盒效果)
scene.background = cubleTExture;

/**
 * 创建带环境贴图的球体
 * 参数说明:
 *   SphereGeometry(半径, 宽度分段, 高度分段)
 *   MeshBasicMaterial 基础材质支持环境贴图
 */
const sphere = new THREE.SphereGeometry(1); // 单位半径的球体
const material = new THREE.MeshBasicMaterial({
  envMap: cubleTExture, // 材质反射环境贴图
});
scene.add(sphere); // 注:原代码中的cube应为sphere
展示效果

实现物体反光和阴影(点光源,环境光源)

受光材质

  • Three.js 中,有一个材质类叫 MeshPhongMaterial。该材质能够通过光源影响其外观,这意味着它适合于需要呈现高光和材质细节的场景。使用 MeshPhongMaterial 时,必须为场景添加光源,以便正确地渲染出材质的反射效果和光影变化。
光源
  • AmbientLight 是环境光,它接受两个参数:第一个是光的颜色,第二个是光的强度。
  • PointLight 是点光源,它接受三个参数:第一个是光的颜色,第二个是光的强度,第三个是光的衰减距离(或范围)。

接受光源/投射效果(阴影)

  • Mesh 中 有 receiveshadowcastshadow 分别是 接受光源和投射阴影
示例
const meterial = new THREE.MeshPhongMaterial({
  color: 0x00ff00,
  shininess: 1000,
});

// 创建MESH
const cubezft = new THREE.Mesh(zft, meterial);
cubezft.position.set(0, 0.5, 0);
//让物体接受光源
cubezft.receiveShadow = true;
//物体投射效果
cubezft.castShadow = true;

const light = new THREE.AmbientLight(0xffffff, 1);
const lightD = new THREE.PointLight(0xffffff, 1000, 100);
lightD.position.set(5, 3, 5);
lightD.castShadow = true;
scene.add(light);
scene.add(cubezft);
//添加点光源
scene.add(lightD);
//创建地面
const meshFloor = new THREE.Mesh(
  //创建地面接受两个参数长宽
  new THREE.PlaneGeometry(20, 20),
  new THREE.MeshPhongMaterial({
    color: 0x1b5e20,
    side: THREE.DoubleSide, //双面都显示
  })
);
//设置位置
meshFloor.position.set(0, 0, -1);
//设置旋转90%
meshFloor.rotation.x -= Math.PI / 2;
//地面也要接受光源
meshFloor.receiveShadow = true;
scene.add(meshFloor);
效果

7. 总结练习

新知识

  • 平移属性 translate 有三个值 X Y Z 接受一个参数 表示平移的单位
控制移动思想
  • 使用键盘侦听事件 @keyDOwn 在此事件中有一个参数 里面包含 keykeyCode 两个对象 key 输出你所点击的键盘 比如我点击 a 它的值为a keyCode 的是以 ASCll码 来存储的 比如 我点击的是 a 则输出 65
  • 使用if判断(也可以使用switch) 判断 你点击的键盘COde值 我使用 wasd来控制前后左右移动 只要判断它对应的code值 然后 使用平移属性 translate 进行一系列的操作

如何让场景跟着移动
首先要让相机看向物体 camera.lookAt 接受三个参数 这里 我直接使用 物体的坐标传入 position
然后 让相机跟随物体 设置 相机位置实时 跟着物体 的坐标 这里我使用的是第三人称的效果 在原有物体的y轴+1 还有x轴加4 可以获得第三视角

示例
  const up = (event) => {
  console.log(event.keyCode);
  console.log(event.key);
  if (event.key === "ArrowUp") {

    cubezft.translateY(0.1);
  } else if (event.key == "ArrowDown") {

    cubezft.translateY(-0.1);
  }else if(event.key === 'ArrowLeft'){
    cubezft.rotation.y +=0.1
  }
  if (event.keyCode === 65) {
    cubezft.translateX(-0.1);
  } else if (event.keyCode === 87) {
    cubezft.translateZ(-0.1);
  } else if (event.keyCode === 68) {
    cubezft.translateX(0.1);
  } else if (event.keyCode === 83) {
    cubezft.translateZ(0.1);
  }else{
    return
  }
  camera.lookAt(cubezft.position);
  
  camera.position.set(
    cubezft.position.x,
    cubezft.position.y + 1,
    cubezft.position.z + 4
  );
};
效果

8. 总结知识点

名称 属性 用法
场景 THREE.Scene() 用于添加和管理3D物体
相机 THREE.PerspectiveCamera() 控制视图视角,实现物体观察或第一人称效果
坐标位置 position 设置物体位置,接受x、y、z三个坐标参数
物体旋转 rotation 控制物体旋转,包含x、y、z三个轴向,可接受具体角度或Math.PI值
立方体 THREE.BoxGeometry() 创建立方体,接受长、宽、高三个参数
圆柱体 THREE.CylinderGeometry() 创建圆柱体,接受四个参数依次为:顶部半径、底部半径、高度、分段数
圆锥 THREE.ConeGeometry(); 创建圆锥体。接受三个参数依次为:底部半径,高度,分段数
胶囊体 THREE.CapsuleGeometry() 创建胶囊体。接受四个参数依次为:半径、柱体长度、帽部分段数、径向分段数
球体 THREE.SphereGeometry 创建球体。接受一个参数:半径
纹理 THREE.TextureLoader().load() 加载普通纹理贴图。参数:图片路径
背景纹理 THREE.CubeTextureLoader().setPath("/").load(); 加载立方体贴图作为全景背景。参数(setPath):图片路径 、参数(load):6张图片路径数组(顺序:右左上下后前)
自定义矩形 THREE.PlaneGeometry() 创建平面,接受四个参数依次为:宽度、高度、宽度分段、高度分段
网格 THREE.Mesh() 创建3D物体,参数:几何体、材质
Phong材质 THREE.MeshPhongMaterial() 创建高光材质,参数:color(颜色)、shininess(高光度)
基础材质 THREE.MeshBasicMaterial() 创建不受光照影响的材质,参数:color(颜色)
标准材质 THREE.MeshStandardMaterial() 创建PBR标准材质,参数:roughness(粗糙度)、metalness(金属度)
物理材质 THREE.MeshPhysicalMaterial() 创建高级PBR材质,参数:clearcoat(清漆层)、transmission(透光率)
Lambert材质 THREE.MeshLambertMaterial() 创建无高光的漫反射材质,参数:color(颜色)
环境光 THREE.AmbientLight() 创建环境光,接受两个参数依次为:颜色、强度
点光源 THREE.PointLight() 创建点光源,接受四个参数依次为:颜色、强度、距离、衰减
平行光 THREE.DirectionalLight() 创建平行光,接受两个参数依次为:颜色、强度
聚光灯 THREE.SpotLight() 创建聚光灯,接受六个参数依次为:颜色、强度、距离、角度、衰减、半影
接受光源 Mesh.receiveShadow 设置物体是否接收阴影,布尔值
投射阴影 Mesh.castShadow 设置物体是否投射阴影,布尔值
使用纹理 THREE.MeshStandardMaterial({map: texture}) 将纹理应用到材质,参数:纹理对象
阴影贴图 renderer.shadowMap.enabled = true 启用渲染器的阴影渲染功能