Three.js插件基础概念

Three.js是一款WebGL框架,用来绘制三维效果的插件。Three.js在WebGL的API接口基础上,进行一层封装。此插件由Mr.doob开发。

一、WEBGL 和 Three.js 的关系

WebGL 原生 API 是一种非常低级的接口,而且还需要一些数学和图形学的相关技术。对于没有相关基础的人来说,入门真的很难,Three.js 将入门的门槛降低了一大截,对 WebGL 进行封装,简化我们创建三维动画场景的过程。
二. 几个基本概念

二、几个基本概念

这张图是Three.js的几个重要对象,构成了三维效果的渲染。

    1. Render 渲染器,主要对象,用于将摄像机(Carmer)视椎体中的三维场景(Scene)渲染成一个二维图片展示在画布上。
    1. Scene 场景图,是一个树状结构,由很多对象组成。一个场景可由多个网格(Mesh), 三维物体(Object3D)、群组(Group)、光源(Light)组成。 场景定义了一些基本要素,还包含背景色、光线等属性。
    1. Carmera 摄像机,它不一定要在场景图中才能起作用,有一半在场景图外,复杂的三维图像可以放置多个摄像机。
    1. Mesh 网格对象,场景图中基本模型,一个网格由一个几何体以及一个或多个材质组成,可以设置旋转、缩放、xyz轴平移距离等属性。
    1. Geometry 几何体,例如球体、立方体、平面等,也可是猫、狗、树等所有能看到的物体。
    1. Material 材质, 用于绘制几何体的表面属性,可以引用一个或多个纹理。将图像包裹在几何体表面,形成不同的物体。
    1. Texture 纹理,一般从由三种获取途径,文件加载、画布绘制、场景渲染的图像。
    1. 光源,可以绘制出不同种类的光。

三、基本使用

了解了Three.js基本概念,下面通过一个案例来看看具体使用,这里我们通过npm来引用插件
  1. 项目中引入插件,npm install three
  2. 引用 import * as THREE from “three” 然后通过 new THREE 的方法来使用

案例代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
var renderer, camera, scene, geometry, material, mesh, stats, gui
//WebGL(全写Web Graphics Library)是一种3D绘图协议,
//可以为HTML5 Canvas提供硬件3D加速渲染,
//这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。
// 初始化渲染器
function initRenderer() {
//实例化渲染器
renderer = new THREE.WebGLRenderer()
//设置宽高
renderer.setSize(window.innerWidth, window.innerHeight)
//添加到DOM
document.body.appendChild(renderer.domElement)
}
// 初始化场景
function initScene() {
// 实例化场景
scene = new THREE.Scene()
}
// 初始化相机
function initCamera() {
//初始化相机
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 200)
camera.position.set(0, 0, 15)
}
// 创建模型
function createMesh() {
// 创建几何体
geometry = new THREE.BoxGeometry(2, 2, 2)
// 创建材质 将法向量映射到 RGB 颜色的材质
material = new THREE.MeshNormalMaterial()
// 创建网格
mesh = new THREE.Mesh(geometry, material)
// 将网格添加到场景
scene.add(mesh)
}

//性能检测框
function initStats() {
stats = new Stats()
// 0: fps, 1: ms, 2: mb, 3+: custom
//stats.showPanel(1)
document.body.appendChild(stats.dom)
}

//创建调试框
function initGui() {
var controls = {
positionX: 0,
positionY: 0,
positionZ: 0
}

gui = new dat.GUI();
gui.add(controls, "positionX", -15, 15).onChange(updatePosition);
gui.add(controls, "positionY", -15, 15).onChange(updatePosition);
gui.add(controls, "positionZ", -15, 15).onChange(updatePosition);

function updatePosition() {
mesh.position.set(controls.positionX, controls.positionY, controls.positionZ);
}
}

// 渲染
function render() {
// 循环调用
requestAnimationFrame(render)
// 每帧网格模型沿x轴旋转0.01弧度,y轴旋转0.02弧度
mesh.rotation.x += 0.01
mesh.rotation.y += 0.02
//更新性能检测框
stats.update()
// 渲染界面
renderer.render(scene, camera)
}

function init() {
//检验浏览器是否支持WEBGL
if (WEBGL.isWebGLAvailable()) {
// 支持 进行渲染
initScene()
initCamera()
initRenderer()
createMesh()
initStats()
initGui()

render()
} else {
var warning = WEBGL.getWebGLErrorMessage();
document.getElementById('container').appendChild(warning);
}
}

init()

效果图(不会做动态图…)


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!