Three.js实践|青训营笔记

140 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天

在之前已经写过两篇关于Three.js的介绍笔记,今天这篇笔记是正式的代码实践笔记。
今天的代码在码上掘金code.juejin.cn/ 上运行,在这里编写类似的demo还是十分方便的。

一、引入Three.js

在项目的开发环境上一般使用 npm install three@0.148.0 --save安装Three库
然后在文件中引入

<script src="./build/three.js"></script>

或者是

<script type="module">
// 现在浏览器支持ES6语法,自然包括import方式引入js文件
import * as THREE from './build/three.module.js';
</script>

然后使用console.log(THREE.Scene);来检查是否引入了Three.js。 在码上掘金中,只需要在JavaScript中使用

import * as THREE from 'three';

即可以引入Three.js

二、创建场景

在之前提到,对于一个Three.js的三个最重要元素:场景相机渲染器,我们首先来创建一个场景,我们对此可以理解为模拟一个生活中的三维世界

const scene = new THREE.Scene()

有了场景之后,我们来定义一个物体形状(仅为定义,并无生成)。这里我们定义了一个立方体,X长度100,Y长度50,Z长度200。除此之外,还有许多形状可以参考开发文档。

const geometry = new THREE.BoxGeometry(100, 50, 200)

然后有形状不行,还需要有材质。材质用于定义物体的外观效果,不同的材质效果不同,我们这里定义一个网格基础材质(不受光源影响)。同理,在文档中还能找到许多其他的材质。

const material = new THREE.MeshBasicMaterial({
  color:0xaaffff,
})

其实到这里,我们还没实现一个物体,所以我们要去使用网格模型Mesh去创建一个物体对象,然后设置他在场景中的位置(默认为原点)

const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0,10,0);

在新建场景、定义形状、定义材质并创建一个物体对象之后,我们再把物体加入场景中。加入之后,在场景中生成了一个物体对象。

scene.add(mesh);

三、创建相机

有了场景之后,我们还需要定义一个相机。在这里我们定义一个之前提到的:透视投影相机,也就是本质上摸模拟人的眼睛去看这个世界的相机。

首先我们实例化一个相机对象。

const camera = new THREE.PerspectiveCamera();

然后设置相机在场景中的三维坐标。

camera.position.set(200, 200, 600);

有了相机的坐标,我们还需要设置相机拍摄的方向,这里我们设置其朝向刚刚新建物体的位置。

camera.lookAt(mesh.position);

虽然在这里我们成功能够拍摄物体,但是其输出的形状是变形的,也就是说直接输出很可能会导致图像变宽或者变高,所以我们需要在新建相机的时候按照一定的规则来定义。

这里我们有一个新的概念:画布。我们在之前定义camera之前定一个画布大小。

const width = 800; 
const height = 500;

PerspectiveCamera( fov, aspect, near, far),这是透视相机的四个参数:

  • fov 代表相机视锥体竖直方向视野角度,默认值为50
  • aspect 代表相机视锥体水平方向和竖直方向长度比,一般设置为Canvas画布宽高比width / height,默认值为1
  • near 代表相机视锥体近裁截面相对相机距离,默认值为0.1
  • far 代表相机视锥体远裁截面相对相机距离,far-near构成了视锥体高度方向,默认值为2000

所以,在这里我们对前面的相机进行重新定义。

const camera = new THREE.PerspectiveCamera(30,width/height,1,3000);

更新之后的相机部分代码应该为:

const width = 800; 
const height = 500;
const camera = new THREE.PerspectiveCamera(30,width/height,1,3000);
camera.position.set(200, 200, 600);
camera.lookAt(mesh.position);

这里之后,我们已经定义了一个透视相机。

四、定义一个渲染器

我们最后只需要定义一个渲染器,便可以透过相机的视角将整个场景渲染出来。首先实例化一个渲染器对象。

const renderer = new THREE.WebGLRenderer();

然后,在这里需要定义一个画布大小,在前面定义相机时我们已经定义了,所以在这里我们直接设置画布大小即可。

renderer.setSize(width, height); 

然后就是渲染,我们使用render函数将场景与相机作为参数传入即可,

renderer.render(scene, camera);

在这里已经渲染出来,但是我们还需要在html中展现出来,这时我们需要在HTML中随便新建一个节点(或者使用原有节点)。

<div id="webgl" style="margin-top: 200px;margin-left: 100px;"></div>

然后在节点中加入渲染出来的节点即可。

document.body.appendChild(renderer.domElement);
document.getElementById('webgl').appendChild(renderer.domElement);

五、效果

通过上面的步骤之后,我们在码上掘金中点击运行即可看到效果。效果应该如下:

image.png

在这里你可以动手改变一下相机的视角或者物体的材质、形状等。