Three.js 超全入门综合案例

Three.js 超全入门综合案例

    • 代码示例
    • 一、文档说明
    • 二、整体运行流程(核心逻辑)
    • 三、核心模块详细解析
      • [1. 基础三要素(必备)](#1. 基础三要素(必备))
        • [1.1 Scene 场景](#1.1 Scene 场景)
        • [1.2 PerspectiveCamera 透视相机](#1.2 PerspectiveCamera 透视相机)
        • [1.3 WebGLRenderer 渲染器](#1.3 WebGLRenderer 渲染器)
      • [2. 轨道控制器 OrbitControls(交互核心)](#2. 轨道控制器 OrbitControls(交互核心))
      • [3. 场景辅助工具(开发调试必备)](#3. 场景辅助工具(开发调试必备))
      • [4. 光照系统(画面质感关键)](#4. 光照系统(画面质感关键))
        • [4.1 AmbientLight 环境光](#4.1 AmbientLight 环境光)
        • [4.2 DirectionalLight 平行光(主光)](#4.2 DirectionalLight 平行光(主光))
        • [4.3 PointLight 点光源(辅光/氛围光)](#4.3 PointLight 点光源(辅光/氛围光))
        • [4.4 补光灯 FillLight](#4.4 补光灯 FillLight)
      • [5. 几何体 \+ PBR 材质 \+ 网格模型](#5. 几何体 + PBR 材质 + 网格模型)
        • [5.1 核心公式](#5.1 核心公式)
        • [5.2 本案例包含几何体](#5.2 本案例包含几何体)
        • [5.3 PBR 物理材质 MeshStandardMaterial](#5.3 PBR 物理材质 MeshStandardMaterial)
        • [5.4 阴影开关](#5.4 阴影开关)
      • [6. 射线拾取 Raycaster(3D交互核心)](#6. 射线拾取 Raycaster(3D交互核心))
      • [7. 窗口自适应](#7. 窗口自适应)
      • [8. 动画系统](#8. 动画系统)
        • [8.1 Clock 时钟](#8.1 Clock 时钟)
        • [8.2 requestAnimationFrame 渲染循环](#8.2 requestAnimationFrame 渲染循环)
    • 四、画面美化核心优化点(解决原版昏暗问题)
    • 五、知识点全覆盖清单
    • 六、运行方式
    • 七、拓展学习方向(进阶)

代码示例

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Three.js 综合入门示例</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            overflow: hidden;
            background: #121826;
            color: #fff;
            font-family: system-ui;
        }

        #info {
            position: absolute;
            top: 12px;
            left: 12px;
            z-index: 10;
            background: rgba(0, 0, 0, 0.45);
            padding: 12px 16px;
            border-radius: 10px;
            font-size: 14px;
            line-height: 1.7;
            backdrop-filter: blur(4px);
        }

        canvas {
            display: block;
        }
    </style>
</head>
<body>
<div id="info">
    Three.js 入门综合示例<br>
    🖱️鼠标拖拽旋转 | 滚轮缩放 | 右键平移<br>
    点击物体,F12控制台查看拾取信息
</div>

<script type="importmap">
    {
      "imports": {
        "three": "https://unpkg.com/three@0.164.1/build/three.module.js",
        "three/addons/": "https://unpkg.com/three@0.164.1/examples/jsm/"
      }
    }
</script>

<script type="module">
    import * as THREE from 'three';
    import {OrbitControls} from 'three/addons/controls/OrbitControls.js';

    // 1.场景、相机、渲染器
    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0x1a2438);
    scene.fog = new THREE.Fog(0x1a2438, 15, 80); // 雾化调远,不会近处灰蒙蒙

    const camera = new THREE.PerspectiveCamera(
        60,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
    );
    camera.position.set(14, 11, 18);

    const renderer = new THREE.WebGLRenderer({antialias: true});
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    renderer.toneMapping = THREE.ACESFilmicToneMapping; // ACES色调映射,画面更通透
    renderer.toneMappingExposure = 1.3; // 整体曝光提亮
    document.body.appendChild(renderer.domElement);

    // 2.轨道控制器
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;
    controls.minDistance = 4;
    controls.maxDistance = 60;

    // 3.辅助
    const axesHelper = new THREE.AxesHelper(9);
    scene.add(axesHelper);

    const gridHelper = new THREE.GridHelper(35, 35, 0x50648c, 0x2c3b58);
    scene.add(gridHelper);

    // 4.光照【大幅提亮】
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.65); // 环境光增强
    scene.add(ambientLight);

    // 主太阳光
    const directionalLight = new THREE.DirectionalLight(0xfffdf5, 1.1);
    directionalLight.position.set(14, 20, 10);
    directionalLight.castShadow = true;
    directionalLight.shadow.mapSize.set(2048, 2048);
    directionalLight.shadow.camera.near = 0.5;
    directionalLight.shadow.camera.far = 80;
    directionalLight.shadow.camera.left = -25;
    directionalLight.shadow.camera.right = 25;
    directionalLight.shadow.camera.top = 25;
    directionalLight.shadow.camera.bottom = -25;
    directionalLight.shadow.bias = -0.0008;
    scene.add(directionalLight);

    // 彩色点光源
    const pointLight = new THREE.PointLight(0xff66aa, 0.8, 30);
    pointLight.position.set(-10, 7, -7);
    pointLight.castShadow = true;
    scene.add(pointLight);

    // 补光,消除死黑角落
    const fillLight = new THREE.PointLight(0xaaccff, 0.4, 40);
    fillLight.position.set(8, 5, -10);
    scene.add(fillLight);

    // 5.物体 PBR材质,调亮色彩
    const cubeGeo = new THREE.BoxGeometry(2.3, 2.3, 2.3);
    const cubeMat = new THREE.MeshStandardMaterial({
        color: 0x44aaff,
        metalness: 0.3,
        roughness: 0.22
    });
    const cubeMesh = new THREE.Mesh(cubeGeo, cubeMat);
    cubeMesh.position.set(-4.5, 1.3, 0);
    cubeMesh.castShadow = true;
    cubeMesh.receiveShadow = true;
    scene.add(cubeMesh);

    const sphereGeo = new THREE.SphereGeometry(1.7, 32, 32);
    const sphereMat = new THREE.MeshStandardMaterial({
        color: 0xff9944,
        metalness: 0.55,
        roughness: 0.18
    });
    const sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);
    sphereMesh.position.set(0, 1.7, -3.5);
    sphereMesh.castShadow = true;
    scene.add(sphereMesh);

    const torusGeo = new THREE.TorusGeometry(1.5, 0.45, 24, 64);
    const torusMat = new THREE.MeshStandardMaterial({
        color: 0x36e0aa,
        metalness: 0.65,
        roughness: 0.16
    });
    const torusMesh = new THREE.Mesh(torusGeo, torusMat);
    torusMesh.position.set(4.8, 1.5, 2.2);
    torusMesh.castShadow = true;
    scene.add(torusMesh);

    // 地面
    const planeGeo = new THREE.PlaneGeometry(45, 45);
    const planeMat = new THREE.MeshStandardMaterial({
        color: 0x232e46,
        metalness: 0,
        roughness: 0.75
    });
    const planeMesh = new THREE.Mesh(planeGeo, planeMat);
    planeMesh.rotation.x = -Math.PI / 2;
    planeMesh.receiveShadow = true;
    scene.add(planeMesh);

    // 6.射线拾取
    const raycaster = new THREE.Raycaster();
    const mouse = new THREE.Vector2();
    window.addEventListener('click', (event) => {
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        raycaster.setFromCamera(mouse, camera);
        const intersects = raycaster.intersectObjects([cubeMesh, sphereMesh, torusMesh]);
        if (intersects.length > 0) {
            const obj = intersects[0].object;
            console.log('✅点击物体:', obj);
        }
    })

    // 7.窗口自适应
    window.addEventListener('resize', () => {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    })

    // 8.动画循环
    const clock = new THREE.Clock();

    function animate() {
        requestAnimationFrame(animate);
        const elapsed = clock.getElapsedTime();

        cubeMesh.rotation.y = elapsed * 0.4;
        sphereMesh.rotation.x = elapsed * 0.32;
        torusMesh.rotation.z = elapsed * 0.55;

        pointLight.position.y = 7 + Math.sin(elapsed * 1.1) * 2.8;

        controls.update();
        renderer.render(scene, camera);
    }

    animate();

</script>
</body>
</html>

一、文档说明

本文为Three.js 入门案例,整合了 Three.js 90% 入门核心知识点。

特点:

  • 画面明亮美观、光影通透、无死黑区域

  • 包含基础三件套、光照、阴影、PBR材质、动画、交互、自适应、射线拾取

  • 代码结构标准,是企业级 Three.js 项目的基础模板

  • 无需本地环境,联网双击 HTML 即可运行

二、整体运行流程(核心逻辑)

Three.js 所有项目固定执行流程

创建场景 → 创建相机 → 创建渲染器 → 初始化灯光/物体 → 绑定控制器 → 动画循环渲染 → 窗口自适应 → 交互监听

三、核心模块详细解析

1. 基础三要素(必备)

Three.js 渲染的核心铁三角,缺一不可。

1.1 Scene 场景

所有模型、灯光、辅助线的容器,相当于"舞台"。

js 复制代码
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x1a2438); // 背景色
scene.fog = new THREE.Fog(0x1a2438,15,80); // 雾化效果

雾化参数:(颜色, 开始距离, 最远可见距离),让场景更有空间层次感。

1.2 PerspectiveCamera 透视相机

模拟人眼视觉,近大远小,最常用的相机类型。

js 复制代码
new THREE.PerspectiveCamera(视场角, 宽高比, 近裁剪面, 远裁剪面)
  • 视场角60°:视觉自然,不畸变

  • 近裁剪面0.1:防止近处模型被裁剪闪烁

  • 远裁剪面1000:适配大范围场景

1.3 WebGLRenderer 渲染器

负责将场景和相机画面绘制到画布上。

关键优化配置:

  • antialias: true:开启抗锯齿,模型边缘顺滑

  • setPixelRatio:适配手机/高分屏,防止模糊

  • toneMapping:电影级色调映射,画面更通透

  • toneMappingExposure:全局曝光提亮,解决画面发黑问题

2. 轨道控制器 OrbitControls(交互核心)

实现鼠标操作3D场景,入门必备:

  • 左键拖拽:旋转视角

  • 滚轮:缩放场景

  • 右键拖拽:平移场景

核心优化:enableDamping 开启阻尼惯性,拖拽手感丝滑、有回弹效果。

3. 场景辅助工具(开发调试必备)

  • AxesHelper 坐标轴:X红、Y绿、Z蓝,快速判断模型朝向

  • GridHelper 网格地面:辅助判断模型位置、高度、空间距离

生产环境可删除,开发调试必加。

4. 光照系统(画面质感关键)

本案例使用三灯组合,解决画面发黑、无层次问题,是行业通用打光方案:

4.1 AmbientLight 环境光

全局漫反射光,无方向、无阴影,提亮整个场景,消除死黑。

4.2 DirectionalLight 平行光(主光)

模拟太阳光,有方向、可投射阴影,是场景的主光源。

阴影优化关键点:

  • shadow.mapSize:阴影分辨率,数值越高越清晰

  • shadow.camera:控制阴影照射范围

  • shadow.bias:解决阴影条纹、锯齿瑕疵

4.3 PointLight 点光源(辅光/氛围光)

模拟灯泡、星光,彩色动态光源,增加画面氛围,可动态浮动动画。

4.4 补光灯 FillLight

填充暗部死角,让模型明暗过渡自然,画面通透柔和。

5. 几何体 + PBR 材质 + 网格模型

5.1 核心公式

网格模型(Mesh) = 几何体(形状) + 材质(外观)

5.2 本案例包含几何体
  • BoxGeometry 立方体

  • SphereGeometry 球体

  • TorusGeometry 圆环体

  • PlaneGeometry 平面地面

5.3 PBR 物理材质 MeshStandardMaterial

工业级写实材质,支持光照、阴影、金属度、粗糙度,是 Three.js 最常用材质:

  • color:基础颜色

  • metalness:金属度 0-1,越高越像金属

  • roughness:粗糙度 0-1,越高越磨砂,越低越光滑反光

5.4 阴影开关
  • castShadow = true:模型投射阴影

  • receiveShadow = true:模型接收阴影

6. 射线拾取 Raycaster(3D交互核心)

实现鼠标点击3D物体,是所有3D点击交互的底层原理。

执行逻辑:

  1. 将鼠标屏幕坐标转为 Three.js 标准化坐标(-1 ~ 1)

  2. 从相机位置发射一条射线穿过鼠标位置

  3. 检测射线与场景物体的相交结果

  4. 判断是否点击到模型,执行对应逻辑

7. 窗口自适应

监听窗口大小变化,动态更新:

  • 相机宽高比

  • 相机投影矩阵

  • 渲染器尺寸

解决窗口拉伸、模型变形问题。

8. 动画系统

8.1 Clock 时钟

获取程序运行时间,基于时间做动画,不依赖帧率,动画丝滑、设备兼容。

8.2 requestAnimationFrame 渲染循环

浏览器原生动画帧,每秒60次刷新画面,实现动态效果:模型旋转、光源浮动、控制器更新。

四、画面美化核心优化点(解决原版昏暗问题)

  1. 开启 ACES 电影级色调映射,画面通透不发灰

  2. 调高全局曝光值,整体提亮场景

  3. 三重灯光组合(环境光+主光+补光),消除暗部死黑

  4. 弱化雾化效果,场景更清晰有层次

  5. 优化材质饱和度与粗糙度,色彩鲜亮质感拉满

  6. 阴影柔和优化,无锯齿、无瑕疵

  7. UI毛玻璃样式,视觉更现代

五、知识点全覆盖清单

本案例一次性掌握以下所有入门核心:

  • ✅ 场景、相机、渲染器三大基础

  • ✅ 轨道控制器鼠标交互

  • ✅ 环境光、平行光、点光源多光源打光

  • ✅ 完整阴影系统与优化

  • ✅ 主流几何体使用

  • ✅ PBR物理写实材质

  • ✅ 场景雾化、背景设置

  • ✅ 坐标轴/网格辅助工具

  • ✅ 射线拾取3D点击交互

  • ✅ 窗口自适应适配

  • ✅ 时间驱动动画系统

  • ✅ 高分屏像素比适配

  • ✅ 电影级色调渲染优化

六、运行方式

  1. 复制完整 HTML 代码,新建文件保存为 three-demo.html

  2. 保证网络正常(加载 Three.js CDN)

  3. 双击文件直接浏览器打开运行

  4. F12 打开控制台,可查看点击拾取日志

七、拓展学习方向(进阶)

  • 纹理贴图(颜色贴图、法线贴图、粗糙度贴图)

  • GLB/GLTF 外部模型加载

  • 粒子系统、星空背景

  • 后期特效(泛光、模糊、调色)

  • GPU 着色器 Shader 动画

相关推荐
唐青枫2 小时前
http-server:别再双击 index.html,一条命令把目录变成网站
前端·javascript
暴力求解2 小时前
Linux网络---传输层协议TCP(二)
linux·服务器·开发语言·网络·tcp/ip
吴声子夜歌2 小时前
Java面试题——基础(一)
java·开发语言
小庞在加油2 小时前
WinDbg实战:QT/跨平台项目死锁与无响应问题排查指南
开发语言·qt·windbg·工具
Vae_Mars3 小时前
C#中的delegate委托
开发语言·c#
一直走下去-明3 小时前
简单的http抓包解包完整代码
开发语言·python
caimouse3 小时前
ReactOS 图形系统分析(51):元文件子系统 — metafile.c
c语言·开发语言
学习星球4 小时前
Solid.js 实战:拆解官方 RealWorld 项目
开发语言·javascript·vue.js
OPEN-F4 小时前
Python进阶教程:正则表达式进阶与文本处理
开发语言·python·正则表达式