2017- 图解WebGL 及Three.js 工作原理
图解WebGL&Three.js 工作原理
一、我们讲什么?
我们讲两个东西:
1、
二、我们为什么要了解原理?
我们假定你对
三、先了解一个基础概念
1、什么是矩阵?
简单说来,矩阵用于坐标变换,如下图:

2、那它具体是怎么变换的呢,如下图:

3、举个实例,将坐标平移

如果这时候,你还是没有理解,没有关系,你只需要知道,矩阵用于坐标变换。
四、WebGL 的工作原理
4.1、WebGL API
在了解一门新技术前,我们都会先看看它的开发文档或者

它只能会点、线、三角形?一定是我看错了。 没有,你没看错。

就算是这样一个复杂的模型,也是一个个三角形画出来的。
4.2、WebGL 绘制流程
简单说来,

接下来,我们分步讲解每个步骤。
4.2.1、获取顶点坐标
顶点坐标从何而来呢?一个立方体还好说,如果是一个机器人呢?没错,我们不会一个一个写这些坐标。 往往它来自三维软件导出,或者是框架生成,如下图:

写入缓存区是啥?
没错,为了简化流程,之前我没有介绍。
由于顶点数据往往成千上万,在获取到顶点坐标后,我们通常会将它存储在显存,即缓存区内,方便
4.2.2、图元装配
我们已经知道,图元装配就是由顶点生成一个个图元(即三角形

我们引入了一个新的名词,叫“顶点着色器”,它由
attribute vec4 position;``void` `main() {`` ``gl_Position = position; ``}
4.2.2.1、顶点着色器处理流程
回到刚才的话题,顶点着色器是如何处理顶点坐标的呢?

如上图,顶点着色器会先将坐标转换完毕,然后由
attribute vec4 position;
void main() {
gl_Position = position;
}
这就是应用了矩阵
4.2.3、光栅化
和图元装配类似,光栅化也是可控的。

在图元生成完毕之后,我们需要给模型“上色”,而完成这部分工作的,则是运行在
precision mediump float;
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
4.2.3.1、片元着色器处理流程
片元着色器具体是如何控制颜色生成的呢?

如上图,顶点着色器是有多少顶点,运行了多少次,而片元着色器则是,生成多少片元(像素
4.3、WebGL 的完整工作流程
至此,实质上,
1、准备数据阶段
在这个阶段,我们需要提供顶点坐标、索引(三角形绘制顺序
2、生成顶点着色器
根据我们需要,由
3、图元装配
4、生成片元着色器
模型是什么颜色,看起来是什么质地,光照效果,阴影(流程较复杂,需要先渲染到纹理,可以先不关注
5、光栅化 能过片元着色器,我们确定好了每个片元的颜色,以及根据深度缓存区判断哪些片元被挡住了,不需要渲染,最终将片元信息存储到颜色缓存区,最终完成整个渲染。

五、Three.js 究竟做了什么?
我们知道,

黄色和绿色部分,都是
- 辅助我们导出了模型数据;
- 自动生成了各种矩阵;
- 生成了顶点着色器;
- 辅助我们生成材质,配置灯光;
- 根据我们设置的材质生成了片元着色器。
而且将
5.1、Three.js 顶点处理流程
从

之前

5.1.1、模型矩阵

现在,我们将模型顺时针旋转
box.rotation.y = Math.PI/6;
但是,如果我们直接将顶点位置用
5.1.2、视图矩阵

然后,我们将相机往上偏移
camera.position.y = 30;
同理,我们用矩阵
5.1.3、投影矩阵

这是我们之前介绍过的了,我们用
5.1.4、应用矩阵
然后,我们编写顶点着色器:
gl_Position = position * modelMatrix * viewMatrix * projectionMatrix;
这样,我们就在

5.2、片元着色器处理流程
我们已经知道片元着色器负责处理材质、灯光等信息,但具体是怎么处理呢? 如下图:

5.3、three.js 完整运行流程:

当我们选择材质后,