Three.js 3D开发学习指南

安装流程

方法一:通过CDN引入

最简单的方法是使用CDN直接在HTML中引入Three.js:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>

方法二:使用npm安装

npm install three

然后在JavaScript文件中导入:

import * as THREE from 'three';

Three.js基础知识

核心概念

  1. 场景(Scene) - 所有3D对象的容器
  2. 相机(Camera) - 决定如何观察场景
  3. 渲染器(Renderer) - 将场景渲染到屏幕上
  4. 几何体(Geometry) - 定义对象的形状
  5. 材质(Material) - 定义对象的外观
  6. 网格(Mesh) - 几何体和材质的组合
  7. 光源(Light) - 创建照明效果

基本工作流程

  1. 创建场景
  2. 添加相机
  3. 创建渲染器
  4. 添加3D对象到场景
  5. 添加光源
  6. 渲染场景

渲染器和场景设置

// 创建渲染器并挂载到DOM
var renderer = new THREE.WebGLRenderer({
    
     canvas: document.getElementById('mainCanvas'), antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor('#000'); // 设置背景色
renderer.shadowMap.enabled = true; // 启用阴影
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 柔和阴影

// 创建场景
var scene = new THREE.Scene();

相机设置

// 创建透视相机
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(3, 3, 5);
camera.lookAt(0, 0, 0);

创建立方体

// 创建几何体
var geometry = new THREE.BoxGeometry(1, 1, 1);

// 为六个面创建不同材质
var materials = [
  new THREE.MeshPhongMaterial({
    
     color: 0xff0000 }), // 右面 - 红色
  new THREE.MeshPhongMaterial({
    
     color: 0x00ff00 }), // 左面 - 绿色
  new THREE.MeshPhongMaterial({
    
     color: 0x0000ff }), // 顶面 - 蓝色
  new THREE.MeshPhongMaterial({
    
     color: 0xffff00 }), // 底面 - 黄色
  new THREE.MeshPhongMaterial({
    
     color: 0xff00ff }), // 前面 - 紫色
  new THREE.MeshPhongMaterial({
    
     color: 0x00ffff })  // 后面 - 青色
];

// 创建网格并添加到场景
var cube = new THREE.Mesh(geometry, materials);
cube.castShadow = true; // 投射阴影
scene.add(cube);

添加光源

// 平行光
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
light.castShadow = true;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
scene.add(light);

// 环境光
var ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);

添加平面接收阴影

var planeGeometry = new THREE.PlaneGeometry(10, 10);
var planeMaterial = new THREE.MeshPhongMaterial({
    
     color: 0xcccccc });
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2; // 水平放置
plane.position.y = -2;
plane.receiveShadow = true; // 接收阴影
scene.add(plane);

响应式调整

window.addEventListener('resize', function () {
    
    
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

动画循环

function animate() {
    
    
  requestAnimationFrame(animate);
  
  // 旋转立方体
  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;
  
  // 渲染场景
  renderer.render(scene, camera);
}

animate();

完整示例

在这里插入图片描述

<!DOCTYPE html>
<html lang="">

<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vite App</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
  <style>
    body {
      
      
      margin: 0;
      overflow: hidden;
    }

    canvas {
      
      
      display: block;
      width: 100%;
      height: 100vh;
    }
  </style>
</head>

<body>
  <!-- <div id="app"></div> -->
  <canvas id="mainCanvas"></canvas>
  <script>
    // 创建渲染器 画布 
    //  挂载到DOM
    var renderer = new THREE.WebGLRenderer({
      
       canvas: document.getElementById('mainCanvas'), antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor('#000'); // 设置渲染器背景为黑色
    renderer.shadowMap.enabled = true; // 开启阴影
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 使用更柔和的阴影

    // 初始化场景
    var scene = new THREE.Scene(); // 创建场景

    //  创建相机(透视相机)
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // 创建透视相机
    camera.position.set(3, 3, 5); // 设置相机位置
    camera.lookAt(0, 0, 0); // 相机看向原点

    // 创建立方体 - 使用不同材质
    var geometry = new THREE.BoxGeometry(1, 1, 1); // 创建一个立方体几何体

    // 为每个面创建不同的材质
    var materials = [
      new THREE.MeshPhongMaterial({
      
       color: 0xff0000 }), // 右面 - 红色
      new THREE.MeshPhongMaterial({
      
       color: 0x00ff00 }), // 左面 - 绿色
      new THREE.MeshPhongMaterial({
      
       color: 0x0000ff }), // 顶面 - 蓝色
      new THREE.MeshPhongMaterial({
      
       color: 0xffff00 }), // 底面 - 黄色
      new THREE.MeshPhongMaterial({
      
       color: 0xff00ff }), // 前面 - 紫色
      new THREE.MeshPhongMaterial({
      
       color: 0x00ffff })  // 后面 - 青色
    ];

    // 创建网格并添加到场景
    var cube = new THREE.Mesh(geometry, materials);
    cube.castShadow = true; // 开启立方体的阴影投射
    scene.add(cube);

    // 增加光源
    var light = new THREE.DirectionalLight(0xffffff, 1); // 创建一个平行光源
    light.position.set(5, 5, 5); // 设置光源位置
    light.castShadow = true; // 设置光源投射阴影

    // 设置阴影贴图的大小,提高阴影质量
    light.shadow.mapSize.width = 1024;
    light.shadow.mapSize.height = 1024;

    scene.add(light); // 将光源添加到场景中

    // 添加环境光,使非直射面也能看到
    var ambientLight = new THREE.AmbientLight(0x404040);
    scene.add(ambientLight);

    // 添加一个平面接收阴影
    var planeGeometry = new THREE.PlaneGeometry(10, 10);
    var planeMaterial = new THREE.MeshPhongMaterial({
      
       color: 0xcccccc });
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.rotation.x = -Math.PI / 2;
    plane.position.y = -2;
    plane.receiveShadow = true; // 平面接收阴影
    scene.add(plane);

    // 处理窗口大小变化
    window.addEventListener('resize', function () {
      
      
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    });

    // 添加动画循环
    function animate () {
      
      
      requestAnimationFrame(animate);

      // 旋转立方体
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;

      // 渲染场景
      renderer.render(scene, camera);
    }

    // 开始动画循环
    animate();
  </script>
</body>

</html>

学习资源

  • Three.js官方文档:https://threejs.org/docs/
  • Three.js示例:https://threejs.org/examples/
  • Three.js中文教程:https://threejsfundamentals.org/threejs/lessons/zh_cn/