Three.js 入门教程:从零构建第一个 3D 场景

作者:像素漫游

时间:2026-10-22

浏览:226

本文详细介绍如何使用 Three.js 在浏览器中创建第一个 3D 场景。内容涵盖场景、相机和渲染器的核心概念,重点解析透视相机的参数设置、WebGL 渲染器的尺寸配置以及 Mesh 对象的创建方法。通过代码示例演示如何添加几何体、材质,并利用 requestAnimationFrame 实现立方体的旋转动画,帮助开发者快速掌握 Three.js 基础开发流程。

文章目录

Three.js 简介与核心概念

Three.js 简介

如果你正在阅读这篇文章,说明你对 Three.js 已有初步了解。这里简要介绍其核心定义:Three.js 是一个 JavaScript 库,旨在简化浏览器中 WebGL 3D 效果的实现。在原生 WebGL 中,绘制一个简单的立方体可能需要数百行 JavaScript 和着色器代码,而使用 Three.js 仅需少量代码即可实现。

本节旨在为 Three.js 提供入门指南。我们将通过构建一个旋转立方体的场景来开始学习。如果在过程中遇到困难,可以参考页面底部提供的完整源码。

构建场景所需的三种核心组件

  • 相机(Camera):决定哪些物体将在屏幕上渲染。
  • 光源(Light):影响材质的显示效果,并决定阴影生成时材质的处理方式。
  • 物体(Object):这是相机视图中主要的渲染对象,例如方块、球体等。

环境准备与基础配置

准备工作

在计算机中保存以下 HTML 代码,确保在 js 目录下包含 three.js 库文件,然后在浏览器中打开该文件。


<html>
 <head>
 <meta charset=utf-8>
 <title>My first three.js app</title>
 <style>
  body { margin: 0; }
  canvas { width: 100%; height: 100% }
 </style>
 </head>
 <body>
 <script src="js/three.js"></script>
 <script>
  // Our Javascript will go here.
 </script>
 </body>
</html>

接下来的代码示例都将嵌入在 script 标签中执行。

场景、相机与渲染器设置

创建示例场景

为了利用 Three.js 进行展示,我们需要三个基本元素:场景(Scene)、摄像机(Camera)和渲染器(Renderer),以便将摄像机视角中的场景渲染出来。


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

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

让我们花点时间解释上述代码的执行过程。我们首先创建了场景、摄像机和渲染器的实例。

Three.js 提供了多种摄像机类型,此处我们使用的是 PerspectiveCamera(透视摄像机)。

其第一个参数是视场角(FOV),表示可见视图的范围,以角度值表示。

第二个参数是宽高比。通常情况下,你应该使用宽度除以高度的比值,否则图像会像老式电影在宽屏电视上播放那样被压扁。

后两个参数分别是近裁剪面(near)和远裁剪面(far)。只有位于这两个面之间的区域才会被渲染。目前你无需深入理解这些参数,但正确设置它们有助于提高性能。

接下来讨论渲染器。这是实现效果的关键部分。除了这里使用的 WebGLRenderer 外,Three.js 还提供了其他渲染器,用于支持不支持 WebGL 的旧版浏览器。

除了创建渲染器实例,我们还需要设置渲染的尺寸。推荐使用填充整个应用窗口的宽高,本例中即为浏览器窗口的宽高。对于性能优先的应用,你可以使用 setSize 方法设置更小的值,例如 window.innerHeight/2 和 window.innerWidth/2,这将渲染一半的尺寸。

如果你想以低分辨率渲染整个尺寸,可以设置 setSize 的第三个参数 updateStyle 为 <font color="#FF1493">false</font>。如果 canvas 元素的宽高均为 100%,则应用将以 1/2 的分辨率进行渲染。

此外,我们需要在 HTML 中添加被渲染的元素。渲染器通过 canvas 元素来展示场景。

创建几何体与材质

“很好,但之前提到的立方体在哪里?”现在我们来添加它。


var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );

camera.position.z = 5;

我们需要使用 BoxGeometry 来创建立方体。该对象包含立方体的所有顶点(vertices)和面(faces)。我们将在后续章节中详细讨论这些概念。

除了几何体,我们还需要材质来为其上色。Three.js 提供了多种材质,但此处我们暂且使用 MeshBasicMaterial。所有材质都接受并应用一个包含所有属性的对象。为简化起见,我们仅提供一个颜色属性:绿色 —— <font color="#00ff00">0x00ff00</font> 。这与 CSS 和 Photoshop 中使用的十六进制颜色表示法相同。

我们需要第三个要素:Mesh。Mesh 是将材质应用到几何体上的对象,创建后我们可以将其放入场景中并自由移动。

当我们调用 scene.add() 时,添加的物体会默认显示在坐标(0, 0, 0)处。这会导致摄像机与立方体内部重叠。为了避免这种情况,我们简单地将摄像机向后移动一点距离。

实现场景渲染与动画循环

渲染场景

如果你在 HTML 文件中复制了上述代码,屏幕将不会显示任何内容,因为我们尚未渲染场景。因此,我们需要调用渲染器或启动动画循环。


function animate() {
 requestAnimationFrame( animate );
 renderer.render( scene, camera );
}
animate();

这会创建一个让渲染器每秒绘制一帧的循环。如果你对网页游戏编程不熟悉,你可能会问“为什么不使用 setInterval 函数呢?”事实上,我们可以这样做,但 requestAnimationFrame 具有更多优势。最重要的好处是,当浏览器切换到另一个标签页时,requestAnimationFrame 会暂停渲染,从而避免浪费宝贵的处理能力和电池寿命。

让立方体动起来

如果你插入了我们刚刚创建的代码,你应该会看到一个绿色的立方体。为了不让画面单调,让我们让它旋转起来。

在 animate 函数中的 renderer.render 上添加如下代码:


cube.rotation.x += 0.01;
cube.rotation.y += 0.01;

这会按帧运行(每秒 60 帧),并赋予立方体优雅的动画效果。基本上,在应用运行时,如果你想移动或改变任何元素,必须通过动画循环来实现。你当然可以在此处调用其他函数,以避免 animate 函数变得过长。

最终结果

恭喜!你现在已经创建了第一个 Three.js 应用。虽然简单,但这总是一个重要的突破。

完整代码参考如下。请仔细琢磨并深刻理解其工作原理。


<html>
 <head>
 <title>My first three.js app</title>
 <style>
  body { margin: 0; }
  canvas { width: 100%; height: 100% }
 </style>
 </head>
 <body>
 <script src="js/three.js"></script>
 <script>
  var scene = new THREE.Scene();
  var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

  var renderer = new THREE.WebGLRenderer();
  renderer.setSize( window.innerWidth, window.innerHeight );
  document.body.appendChild( renderer.domElement );

  var geometry = new THREE.BoxGeometry( 1, 1, 1 );
  var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
  var cube = new THREE.Mesh( geometry, material );
  scene.add( cube );

  camera.position.z = 5;

  var animate = function () {
  requestAnimationFrame( animate );

  cube.rotation.x += 0.1;
  cube.rotation.y += 0.1;

  renderer.render(scene, camera);
  };

  animate();
 </script>
 </body>
</html>

总结

以上就是本文的全部内容,希望本文的内容对大家的学习或工作具有一定的参考学习价值。如果有疑问,欢迎留言交流,谢谢大家对本站的支持。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章