1. 第一个Three.js程序:旋转立方体(完整实战教程)

1.1. 项目准备

1.1.1. 环境搭建(三种方式任选)

1.1.1.1. 方式一:CDN快速开始(推荐初学者)

创建文件:index.html

html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>第一个Three.js程序:旋转立方体</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            overflow: hidden;
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
            color: #fff;
        }

        #info-panel {
            position: absolute;
            top: 20px;
            left: 20px;
            background: rgba(0, 0, 0, 0.7);
            padding: 20px;
            border-radius: 12px;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.1);
            max-width: 400px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
            z-index: 100;
        }

        #info-panel h1 {
            margin-bottom: 10px;
            color: #4facfe;
            font-size: 24px;
        }

        #info-panel p {
            margin-bottom: 8px;
            line-height: 1.5;
            color: #aaa;
        }

        #info-panel code {
            background: rgba(79, 172, 254, 0.1);
            padding: 2px 6px;
            border-radius: 4px;
            font-family: 'Monaco', 'Consolas', monospace;
        }

        #controls {
            position: absolute;
            bottom: 20px;
            left: 20px;
            display: flex;
            gap: 10px;
            z-index: 100;
        }

        .control-btn {
            background: rgba(79, 172, 254, 0.2);
            border: 1px solid rgba(79, 172, 254, 0.3);
            color: white;
            padding: 10px 20px;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.3s ease;
            font-size: 14px;
        }

        .control-btn:hover {
            background: rgba(79, 172, 254, 0.4);
            transform: translateY(-2px);
        }

        .control-btn.active {
            background: rgba(79, 172, 254, 0.6);
            box-shadow: 0 0 20px rgba(79, 172, 254, 0.4);
        }

        #stats {
            position: absolute;
            top: 20px;
            right: 20px;
            z-index: 100;
        }

        #fullscreen-btn {
            position: absolute;
            bottom: 20px;
            right: 20px;
            background: rgba(255, 255, 255, 0.1);
            border: none;
            color: white;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            cursor: pointer;
            font-size: 18px;
            z-index: 100;
        }

        #fps-counter {
            position: absolute;
            top: 60px;
            right: 20px;
            background: rgba(0, 0, 0, 0.5);
            padding: 5px 10px;
            border-radius: 4px;
            font-family: 'Monaco', 'Consolas', monospace;
            font-size: 12px;
            z-index: 100;
        }
    </style>
</head>
<body>
    <!-- 信息面板 -->
    <div id="info-panel">
        <h1>🎯 第一个Three.js程序</h1>
        <p><strong>✨ 旋转立方体 ✨</strong></p>
        <p>这是Three.js的入门程序</p>
    </div>

    <!-- Three.js库引入 -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.135.0/build/three.min.js"></script>
    <!-- 性能监控库 -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.135.0/examples/js/libs/stats.min.js"></script>
    <!-- 控制器 -->
    <script src="https://cdn.jsdelivr.net/npm/three@0.135.0/examples/js/controls/OrbitControls.js"></script>

    <!-- 主程序 -->
    <script>
        // 主程序开始...
    </script>
</body>
</html>

1.1.1.2. 方式二:本地开发环境

创建项目结构:

text

my-first-threejs/
├── index.html
├── css/
│   └── style.css
├── js/
│   ├── main.js
│   └── utils.js
├── textures/          # 纹理图片
│   ├── wood.jpg
│   └── metal.jpg
├── models/           # 3D模型(可选)
└── README.md

1.1.1.3. 方式三:使用构建工具(Vite)

bash

# 创建项目
npm create vite@latest my-threejs-app -- --template vanilla

# 进入项目目录
cd my-threejs-app

# 安装Three.js
npm install three

# 启动开发服务器
npm run dev

1.2. 完整代码实现

1.2.1. 基础版本

javascript

// 在主script标签中编写以下代码:

// ============ 1. 初始化基础组件 ============
// 创建场景(容器)
const scene = new THREE.Scene();

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

// 创建渲染器(画布)
const renderer = new THREE.WebGLRenderer({ 
    antialias: true, // 开启抗锯齿
    alpha: true      // 开启透明度
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

// ============ 2. 创建立方体 ============
// 创建立方体几何体(宽, 高, 深)
const geometry = new THREE.BoxGeometry(1, 1, 1);

// 创建立方体材质
const material = new THREE.MeshBasicMaterial({ 
    color: 0x00ff00, // 绿色
    wireframe: false  // 非线框模式
});

// 创建网格(几何体 + 材质)
const cube = new THREE.Mesh(geometry, material);

// 将立方体添加到场景中
scene.add(cube);

// 设置相机位置(否则什么都看不到)
camera.position.z = 5;

// ============ 3. 创建动画循环 ============
function animate() {
    // 请求下一帧动画
    requestAnimationFrame(animate);

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

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

// 启动动画
animate();

// ============ 4. 响应窗口大小变化 ============
window.addEventListener('resize', () => {
    // 更新相机宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    // 更新渲染器大小
    renderer.setSize(window.innerWidth, window.innerHeight);
});

1.3. 分步详细解释

1.3.1. 第一步:理解三大核心组件

javascript

// 场景 (Scene) - 容器,存放所有3D对象
const scene = new THREE.Scene();

// 相机 (Camera) - 观察者的视角
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// 渲染器 (Renderer) - 将3D场景渲染到2D画布上
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

1.3.2. 第二步:创建立方体

javascript

// 几何体 (Geometry) - 定义物体的形状
// BoxGeometry(宽度, 高度, 深度, 宽度分段数, 高度分段数, 深度分段数)
const geometry = new THREE.BoxGeometry(1, 1, 1);

// 材质 (Material) - 定义物体的外观
// MeshBasicMaterial 是最基础的材质,不受光照影响
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

// 网格 (Mesh) - 几何体和材质的结合体
const cube = new THREE.Mesh(geometry, material);

// 添加到场景
scene.add(cube);

1.3.3. 设置相机位置

javascript

// 默认相机在原点(0,0,0),立方体也在原点(0,0,0)
// 所以我们需要将相机向后移动才能看到立方体
camera.position.z = 5;

1.3.4. 第四步:创建动画循环

javascript

// 动画循环函数
function animate() {
    // 1. 请求下一帧动画(浏览器优化的动画API)
    requestAnimationFrame(animate);

    // 2. 更新立方体的旋转
    cube.rotation.x += 0.01;  // 绕X轴旋转
    cube.rotation.y += 0.01;  // 绕Y轴旋转

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

// 启动动画
animate();

1.3.5. 第五步:响应式处理

javascript

// 监听窗口大小变化
window.addEventListener('resize', () => {
    // 更新相机的宽高比
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix(); // 必须调用此方法更新

    // 更新渲染器大小
    renderer.setSize(window.innerWidth, window.innerHeight);
});

1.4. 完整项目结构(推荐)

text

first-threejs-project/
├── index.html              # 主页面
├── css/
│   └── style.css          # 样式文件
├── js/
│   ├── main.js            # 主逻辑
│   ├── cube.js            # 立方体类
│   ├── controls.js        # 控制逻辑
│   └── utils.js           # 工具函数
├── textures/              # 纹理图片
│   ├── wood.jpg
│   ├── metal.jpg
│   └── stone.jpg
├── fonts/                 # 字体文件(可选)
├── models/                # 3D模型(可选)
└── README.md              # 项目说明

1.5. 总结

通过这个"旋转立方体"项目,你已经学会了:

  1. ✅ Three.js的基础架构

  2. ✅ 创建3D对象和材质

  3. ✅ 设置相机和渲染器

  4. ✅ 实现动画循环

这是Three.js学习的起点,掌握了这些基础概念后,你就可以继续学习更高级的功能了。记住,实践是最好的学习方法,尝试修改代码参数,看看会发生什么变化!

学习资源推荐:

祝你学习顺利! 🚀