从零开始学习three.js(1):一个完整项目指南

5,271 阅读7分钟

three.js 是一个功能强大的 JavaScript 图形库,用于在浏览器中创建三维图形和交互式可视化效果。它由 Ethan Demello 和 Mike Bosted 于 2010 年开发,并迅速成为前端开发者必备的工具之一。

本文将带您一步步从安装three.js 开始,到创建一个完整的案例程序,展示如何利用three.js 实现各种三维效果和交互。官方地址:threejs.org/

前言

three.js 的主要目标是简化 WebGL 技术的使用,通过提供一系列封装好的 API 和组件,让开发者能够快速构建三维应用。无论您是想要制作游戏、虚拟现实应用,还是WebGL 项目,three.js 都是一个强大的工具。

在开始之前,请确保您的浏览器支持所有必要的 WebGL 版本,并且您的 JavaScript 引擎已启用 ECMAScript 6 语法糖和 Web ARRs(实验特性)。

1. 安装与配置

1.1 安装three.js 库

three.js 提供了两种安装方式:通过 CDN 或者自定义路径。

使用 CDN:

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>

自定义路径:

如果您的项目需要特定的版本或修改,可以选择下载并安装three.js 库。

npm install three@latest

1.2 配置项目

在项目中导入以下文件:

  • index.html:用于创建 HTML 页面。
  • style.css:设置页面样式和布局。
  • src/your_project.js:主要脚本文件,用于初始化three.js 环境并运行代码。

完成这些步骤后,您应该能够看到浏览器中的默认场景设置。如果出现错误,请检查网络连接或查看浏览器的开发者工具(Ctrl+Shift+I)。

2. 创建基本项目

2.1 创建 HTML 文件

以下是一个示例的 HTML 结构:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <title>three.js 教程</title>
    <!-- 其他样式表,如自定义主题或布局 -->
</head>
<body>
    <!-- JavaScript 脚本代码 -->
</body>
</html>

2.2 添加three.js 库

在 HTML 的头部分析器中添加以下代码:

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>

或者,如果使用自定义路径,则将文件路径替换为 src/your_project.js

2.3 初始化three.js 环境

在 body 脚本部分添加以下代码:

// 在初始化three.js 环境之前,请确保您已经配置了浏览器的前端设置。
// 您可以使用以下代码进行测试:
// https://开发者文档three.js.org/en/v120/browsers/quickstart#quickstart

// 初始化场景、相机和 renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });

// 设置 renderer 的目标元素
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);

document.body.appendChild(renderer.domElement);

// 添加场景中的物体
// 创建一个简单的球体
const geometry = new THREE.SphereGeometry(1, 32, 32);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);

// 设置相机位置,使其可以观察到球体
camera.position.z = 5;

// 显示渲染结果
renderer.render(scene, camera);

3. 使用three.js 的高级功能

3.1 添加几何体和材质

three.js 提供了许多内置几何体,如球体、立方体、圆柱体等。您还可以为这些几何体设置不同的材质。

// 创建一个立方体
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshPhongMaterial({ color: 0xff0000 });
const box = new THREE.Mesh(geometry, material);

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

3.2 添加灯光

灯光是渲染三维场景中非常重要的组件。three.js 提供了多种类型的灯光,包括平行光、点光源、环境光源和聚光灯。

// 创建平行光源并将其添加到场景中
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 3, 5);

scene.add(light);

3.3 添加文字说明

您也可以在场景中添加文字,方便用户理解代码的功能。

// 在场景中添加文本说明
const text = new THREE.TextGeometry('Hello World', 'font.sans-serif');
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const textObject = new THREE.Mesh(text, material);

textObject.position.y = -2;
scene.add(textObject);

3.4 添加自定义组件

为了提高代码的复用性,您可以创建一个自定义组件并将其添加到场景中。

// 创建一个自定义组件
const MyComponent = function() {
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    const renderer = new THREE.WebGLRenderer({ antialias: true });

    // 设置 renderer 的大小和比例
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(window.devicePixelRatio);

    document.body.appendChild(renderer.domElement);

    // 添加一个球体到场景中
    const geometry = new THREE.SphereGeometry(1, 32, 32);
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    this.sphere = new THREE.Mesh(geometry, material);
    this.scene.add(this.sphere);

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

    // 显示渲染结果
    renderer.render(this.scene, this.camera);
};

// 在场景中添加自定义组件
scene.add(new MyComponent());

4. 配置场景的渲染设置

4.1 设置相机参数

您可以根据需要调整相机的参数,例如焦距、视角等。

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

其中:

  • 75 是相机的垂直视角(field of view,fov)。
  • window.innerWidth / window.innerHeight 是相机的宽高比。

4.2 添加场景中的其他组件

例如,您还可以添加网格、天空盒等元素来丰富场景。

// 添加一个平行光
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 3, 5);

scene.add(light);

// 添加一个网格
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshPhongMaterial({ color: 0x808080 });
const box = new THREE.Mesh(geometry, material);
box.position.y = -2;
scene.add(box);

// 添加一个天空盒
const skyBox = new THREE.Skybox();
skyBox.position.y = -1.5;

scene.add(skyBox);

4.3 配置渲染设置

您可以使用three.js 提供的高级功能来优化渲染性能。

var renderer = new THREE.WebGLRenderer({ //创建渲染器对象
    // canvas: document.getElementById('can3d'), //渲染器绘制其输出的画布,
    alpha: false, // 画布是否包含alpha(透明度)缓冲区。默认值为falsepremultipliedAlpha: true, //渲染器是否会假设颜色具有 预乘alpha。默认为trueantialias: true, //是否执行抗锯齿。默认值为falsepreserveDrawingBuffer: true, //是否保留缓冲区直到手动清除或覆盖。默认值为falsedepth: true, //绘图缓冲区是否具有至少16位的 深度缓冲区。默认为trueautoClear: true, //定义渲染器是否应在渲染帧之前自动清除其输出。
    //以上为基础配置选项。
    //以下为高级进阶调渲染后期
    gammaFactor: 0.5, //伽马基础值
    gammaInput: true, //如果设置,那么它期望所有纹理和颜色都是预乘伽马。默认值为falsegammaOutput: true, //如果设置,那么它期望所有纹理和颜色需要以预乘伽马输出。默认值为falseshadowMap: null, //如果使用,它包含阴影贴图的引用。
    physicalCorrectLights: true, //是否使用物理上正确的照明模式。默认值为falsepowerPreference: 'high-performance', // 或者 'low-power'toneMapping: 0.5, //曝光值
    toneMappingExposure: 1, //色调映射的曝光级别。默认值为1renderLists: [], //在内部用于处理场景对象渲染的排序
    sortObjects: true //定义渲染器是否应对对象进行排序。默认为true。
})

5. 完成并运行代码

在完成所有必要的配置和组件添加后,您就可以运行代码并查看结果。

<!DOCTYPE html>
<html>
<head>
    <title>Three.js 教程</title>
    <!-- 其他样式表 -->
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        // 初始化场景、相机和 renderer
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true });

        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(window.devicePixelRatio);

        document.body.appendChild(renderer.domElement);

        // 添加场景中的物体
        const geometry = new THREE.SphereGeometry(1, 32, 32);
        const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        const sphere = new THREE.Mesh(geometry, material);
        scene.add(sphere);

        camera.position.z = 5;

        renderer.render(scene, camera);
    </script>
</body>
</html>

6. 测试和优化

运行代码后,您可以根据需要测试不同的配置,并进行优化。例如,调整分辨率、改进图形效果等。

通过以上步骤,您可以轻松开始使用three.js 创建三维场景并展示您的项目。three.js 提供了丰富的功能和文档资源,您可以随时参考官方文档了解更多的细节。 

以下是一个使用 Three.js 创建简单三维场景的完整 HTML 文件示例:

<!DOCTYPE html>
<html>
<head>
    <title>Three.js 教程</title>
    <style>
        /* 自定义样式 */
        body {
            margin: 0;
            overflow: hidden;
        }
        canvas {
            display: block;
        }
        #three-container {
            position: relative;
        }
    </style>
</head>
<body>
    <div id="three-container"></div>

    <!-- 包含 Three.js 和相关库的链接 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        // 初始化场景、相机和渲染器
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true });

        // 设置渲染器的大小和比例
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(window.devicePixelRatio);

        // 将渲染器附加到 body 元素的 DOM 结构中
        document.body.appendChild(renderer.domElement);

        // 添加场景中的物体 - 球体
        const geometry = new THREE.SphereGeometry(1, 32, 32);
        const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
        const sphere = new THREE.Mesh(geometry, material);
        scene.add(sphere);

        // 设置相机位置,使其可以观察到球体
        camera.position.z = 5;

        // 显示渲染结果
        renderer.render(scene, camera);
    </script>
</body>
</html>

执行步骤:

  1. 保存文件为 .html,并在浏览器中打开。
  2. 在控制台输入以下命令以查看日志信息:
console.log('Hello, Three.js!');

添加更多组件的示例:

  • 平行光
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 3, 5);
scene.add(light);
  • 网格(如盒子)
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshPhongMaterial({ color: 0x808080 });
const box = new THREE.Mesh(geometry, material);
box.position.y = -2;
scene.add(box);
  • 天空盒
const skyBox = new THREE.Skybox();
scene.add(skyBox);

完整示例:

<!DOCTYPE html>
<html>
<head>
    <title>Three.js 教程</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
        canvas {
            display: block;
        }
        #three-container {
            position: relative;
        }
    </style>
</head>
<body>
    <div id="three-container"></div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        // 初始化场景、相机和渲染器
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({ antialias: true });

        // 设置渲染器的大小和比例
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(window.devicePixelRatio);

        // 将渲染器附加到 body 元素的 DOM 结构中
        document.body.appendChild(renderer.domElement);

        // 添加场景中的物体 - 球体
        const geometry = new THREE.SphereGeometry(1, 32, 32);
        const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
        const sphere = new THREE.Mesh(geometry, material);
        scene.add(sphere);

        // 设置相机位置,使其可以观察到球体
        camera.position.z = 5;

        // 添加平行光
        const light = new THREE.DirectionalLight(0xffffff, 1);
        light.position.set(5, 3, 5);
        scene.add(light);

        // 添加网格(如盒子)
        const geometry = new THREE.BoxGeometry();
        const material = new THREE.MeshPhongMaterial({ color: 0x808080 });
        const box = new THREE.Mesh(geometry, material);
        box.position.y = -2;
        scene.add(box);

        // 添加天空盒
        const skyBox = new THREE.Skybox();
        scene.add(skyBox);

        // 显示渲染结果
        renderer.render(scene, camera);
    </script>
</body>
</html>

更多three.js、cesium.js开源案例,请移至gitee.com/giser2017/t…