前端初识threejs

483 阅读3分钟

Three.js 入门指南:从零开始创建 3D 场景

前言

Three.js 是一个强大的 JavaScript 3D 库,它让 Web 开发者能够轻松地在浏览器中创建和展示 3D 图形。本文将带你从零开始学习 Three.js,通过实际案例掌握其核心概念和基本用法。

什么是 Three.js?

Three.js 是一个基于 WebGL 的 JavaScript 3D 库,它封装了 WebGL 的复杂性,提供了更简单、更直观的 API。使用 Three.js,你可以:

  • 创建复杂的 3D 场景
  • 添加光照和阴影
  • 加载 3D 模型
  • 实现动画效果
  • 处理用户交互

环境准备

首先,我们需要创建一个基本的项目结构:

mkdir threejs-demo
cd threejs-demo
npm init -y
npm install three

然后创建一个简单的 HTML 文件:

<!DOCTYPE html>
<html>
<head>
    <title>Three.js Demo</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script type="module" src="./main.js"></script>
</body>
</html>

第一个 3D 场景

让我们创建一个简单的 3D 场景,包含一个旋转的立方体:

// main.js
import * as THREE from 'three';

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

// 创建相机
const camera = new THREE.PerspectiveCamera(
    75, // 视场角
    window.innerWidth / window.innerHeight, // 宽高比
    0.1, // 近平面
    1000 // 远平面
);

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建立方体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 设置相机位置
camera.position.z = 5;

// 动画循环
function animate() {
    requestAnimationFrame(animate);
    
    // 旋转立方体
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
    
    renderer.render(scene, camera);
}

animate();

核心概念解析

1. 场景(Scene)

场景是 Three.js 中所有对象的容器。你可以把它想象成一个舞台,所有的 3D 对象都在这个舞台上表演。

const scene = new THREE.Scene();

2. 相机(Camera)

相机决定了我们如何观察场景。Three.js 提供了多种相机类型,最常用的是透视相机(PerspectiveCamera)。

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

3. 渲染器(Renderer)

渲染器负责将场景和相机的内容渲染到网页上。

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);

4. 几何体(Geometry)

几何体定义了 3D 对象的形状。Three.js 提供了多种基本几何体,如立方体、球体、圆柱体等。

const geometry = new THREE.BoxGeometry();

5. 材质(Material)

材质定义了对象的外观,包括颜色、纹理、透明度等属性。

const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

6. 网格(Mesh)

网格是几何体和材质的组合,是实际显示在场景中的对象。

const cube = new THREE.Mesh(geometry, material);

进阶功能

添加光照

// 添加环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);

// 添加点光源
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(10, 10, 10);
scene.add(pointLight);

加载 3D 模型

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const loader = new GLTFLoader();
loader.load(
    'path/to/model.gltf',
    function (gltf) {
        scene.add(gltf.scene);
    },
    undefined,
    function (error) {
        console.error('An error happened:', error);
    }
);

添加交互

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

性能优化建议

  1. 使用 BufferGeometry 代替 Geometry
  2. 合并几何体以减少绘制调用
  3. 使用 LOD(Level of Detail)技术
  4. 合理使用 FrustumCulling
  5. 注意内存管理,及时释放不需要的资源

实际应用案例

1. 3D 产品展示

// 创建产品展示场景
const productScene = new THREE.Scene();
const productCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// 加载产品模型
const loader = new GLTFLoader();
loader.load('product.gltf', (gltf) => {
    const product = gltf.scene;
    productScene.add(product);
    
    // 添加环境光
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    productScene.add(ambientLight);
    
    // 添加点光源
    const pointLight = new THREE.PointLight(0xffffff, 1);
    pointLight.position.set(10, 10, 10);
    productScene.add(pointLight);
});

2. 3D 数据可视化

// 创建数据可视化场景
const dataScene = new THREE.Scene();
const dataCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// 创建柱状图
function createBarChart(data) {
    data.forEach((value, index) => {
        const height = value * 0.1;
        const geometry = new THREE.BoxGeometry(0.5, height, 0.5);
        const material = new THREE.MeshPhongMaterial({ color: 0x3498db });
        const bar = new THREE.Mesh(geometry, material);
        
        bar.position.x = index - data.length / 2;
        bar.position.y = height / 2;
        
        dataScene.add(bar);
    });
}

总结

Three.js 为 Web 开发者提供了强大的 3D 图形能力。通过本文的学习,你应该已经掌握了 Three.js 的基本概念和核心功能。要深入学习 Three.js,建议:

  1. 阅读官方文档
  2. 查看示例代码
  3. 参与开源项目
  4. 实践各种 3D 效果

记住,3D 开发是一个需要不断实践和探索的领域,保持好奇心和创造力,你就能创造出令人惊叹的 3D 作品!

参考资料