图解WebGL&Three.js工做原理(转载)

去年的时候,有研究3D 可视化项目,用three.js 作了个3D可视化监控V1版本,主要参照的是
郭隆邦技术博客http://www.yanhuangxueyuan.co...
three editor https://threejs.org/editor/
form-generator https://mrhj.gitee.io/form-ge...
学习three的时候,看用户文档仍是比较头疼,不少东西不知道如何查看,只能挨着找demo,找到类似效果,而后查demo代码找关键API,在去看官方docs,以前没有webgl基础,学习three能够作出相关功能,可是具体是怎么实现的,并不了解。今年打算学习下webgl,在w3cschool上面看webgl的知识,比较枯燥,没有完整代码。不少术语都看不懂,还须要一个个去搜索。今天无心翻到图解webgl&three.js工做原理,以为写的比较好,故转载过来多学习几遍,也能够帮助更多人来了解它们的原理。好吧,咱们一块儿来学习吧!javascript

1、咱们讲什么?

咱们讲两个东西:
一、WebGL背后的工做原理是什么?
二、以Three.js为例,讲述框架在背后扮演什么样的角色?html

2、咱们为何要了解原理?

咱们假定你对WebGL已经有必定了解,或者用Three.js作过了一些东西,这个时候,你可能碰到了这样一些问题:
一、不少东西仍是作不出来,甚至没有任何思路;
二、碰到bug没法解决,甚至没有方向;
三、性能出现问题,彻底不知道如何去优化。
这个时候,咱们须要了解更多。java

3、先了解一个基础概念 

一、什么是矩阵?
简单说来,矩阵用于坐标变换,以下图:
git

二、那它具体是怎么变换的呢,以下图:
web

三、举个实例,将坐标平移2,以下图:
编程

若是这时候,你仍是没有理解,没有关系,你只须要知道,矩阵用于坐标变换。浏览器

4、WebGL的工做原理

4.一、WebGL API

在了解一门新技术前,咱们都会先看看它的开发文档或者API。
查看Canvas的绘图API,咱们会发现它能画直线、矩形、圆、弧线、贝塞尔曲线。
因而,咱们看了看WebGL绘图API,发现:
缓存

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

就算是这样一个复杂的模型,也是一个个三角形画出来的。性能

4.二、WebGL绘制流程

简单说来,WebGL绘制过程包括如下三步:
一、获取顶点坐标
二、图元装配(即画出一个个三角形)
三、光栅化(生成片元,即一个个像素点)

接下来,咱们分步讲解每一个步骤。

4.2.一、获取顶点坐标

顶点坐标从何而来呢?一个立方体还好说,若是是一个机器人呢?
没错,咱们不会一个一个写这些坐标。
每每它来自三维软件导出,或者是框架生成,以下图:

写入缓存区是啥?
没错,为了简化流程,以前我没有介绍。
因为顶点数据每每成千上万,在获取到顶点坐标后,咱们一般会将它存储在显存,即缓存区内,方便GPU更快读取。

4.2.二、图元装配

咱们已经知道,图元装配就是由顶点生成一个个图元(即三角形)。那这个过程是自动完成的吗?答案是并不是彻底如此。
为了使咱们有更高的可控性,即自由控制顶点位置,WebGL把这个权力交给了咱们,这就是可编程渲染管线(不用理解)。
WebGL须要咱们先处理顶点,那怎么处理呢?咱们先看下图:

咱们引入了一个新的名词,叫“顶点着色器”,它由opengl es编写,由javascript以字符串的形式定义并传递给GPU生成。
好比以下就是一段顶点着色器代码:

1

2

3

4

attribute vec4 position;

void main() {

gl_Position = position;

}

attribute修饰符用于声明由浏览器(javascript)传输给顶点着色器的变量值;
position即咱们定义的顶点坐标;
gl_Position是一个内建的传出变量。
这段代码什么也没作,若是是绘制2d图形,没问题,但若是是绘制3d图形,即传入的顶点坐标是一个三维坐标,咱们则须要转换成屏幕坐标。
好比:v(-0.5, 0.0, 1.0)转换为p(0.2, -0.4),这个过程相似咱们用相机拍照。(该转换没太看懂 屏幕坐标跟V坐标是如何转换过来的,有知道的能够解释下吗?)

4.2.2.一、顶点着色器处理流程

回到刚才的话题,顶点着色器是如何处理顶点坐标的呢?

如上图,顶点着色器会先将坐标转换完毕,而后由GPU进行图元装配,有多少顶点,这段顶点着色器程序就运行了多少次。
你可能留意到,这时候顶点着色器变为:

attribute vec4 position;

uniform mat4 matrix;

void main() {

gl_Position = position * matrix;

}

这就是应用了矩阵matrix,将三维世界坐标转换成屏幕坐标,这个矩阵叫投影矩阵,由javascript传入,至于这个matrix怎么生成,咱们暂且不讨论。

4.2.三、光栅化

和图元装配相似,光栅化也是可控的。

在图元生成完毕以后,咱们须要给模型“上色”,而完成这部分工做的,则是运行在GPU的“片元着色器”来完成。
它一样是一段opengl es程序,模型看起来是什么质地(颜色、漫反射贴图等)、灯光等由片元着色器来计算。
以下是一段简单的片元着色器代码:

1

2

3

4

precision mediump float`;`

void main(`void`) {

gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);

}

gl_FragColor即输出的颜色值。

4.2.3.一、片元着色器处理流程

片元着色器具体是如何控制颜色生成的呢?

如上图,顶点着色器是有多少顶点,运行了多少次,而片元着色器则是,生成多少片元(像素),运行多少次。

4.三、WebGL的完整工做流程

至此,实质上,WebGL经历了以下处理流程:
一、准备数据阶段
在这个阶段,咱们须要提供顶点坐标、索引(三角形绘制顺序)、uv(决定贴图坐标)、法线(决定光照效果),以及各类矩阵(好比投影矩阵)。
其中顶点数据存储在缓存区(由于数量巨大),以修饰符attribute传递给顶点着色器;
矩阵则以修饰符uniform传递给顶点着色器。
二、生成顶点着色器
根据咱们须要,由Javascript定义一段顶点着色器(opengl es)程序的字符串,生成而且编译成一段着色器程序传递给GPU。
三、图元装配
GPU根据顶点数量,挨个执行顶点着色器程序,生成顶点最终的坐标,完成坐标转换。
四、生成片元着色器
模型是什么颜色,看起来是什么质地,光照效果,阴影(流程较复杂,须要先渲染到纹理,能够先不关注),都在这个阶段处理。
五、光栅化
能过片元着色器,咱们肯定好了每一个片元的颜色,以及根据深度缓存区判断哪些片元被挡住了,不须要渲染,最终将片元信息存储到颜色缓存区,最终完成整个渲染。

5、Three.js究竟作了什么?

咱们知道,three.js帮咱们完成了不少事情,可是它具体作了什么呢,他在整个流程中,扮演了什么角色呢?
咱们先简单看一下,three.js参与的流程:

黄色和绿色部分,都是three.js参与的部分,其中黄色是javascript部分,绿色是opengl es部分。
咱们发现,能作的,three.js基本上都帮咱们作了。

  • 辅助咱们导出了模型数据;
  • 自动生成了各类矩阵;
  • 生成了顶点着色器;
  • 辅助咱们生成材质,配置灯光;
  • 根据咱们设置的材质生成了片元着色器。

并且将webGL基于光栅化的2D API,封装成了咱们人类能看懂的 3D API。

5.一、Three.js顶点处理流程

从WebGL工做原理的章节中,咱们已经知道了顶点着色器会将三维世界坐标转换成屏幕坐标,但实际上,坐标转换不限于投影矩阵。
以下图:

以前WebGL在图元装配以后的结果,因为咱们认为模型是固定在坐标原点,而且相机在x轴和y轴坐标都是0,其实正常的结果是这样的:

5.1.一、模型矩阵

如今,咱们将模型顺时针旋转Math.PI/6,全部顶点位置确定都变化了。

1

box.rotation.y = Math.PI/6;

可是,若是咱们直接将顶点位置用javascript计算出来,那性能会很低(顶点一般成千上万),并且,这些数据也很是不利于维护。
因此,咱们用矩阵modelMatrix将这个旋转信息记录下来。

5.1.二、视图矩阵

而后,咱们将相机往上偏移30。

1

camera.position.y = 30;

同理,咱们用矩阵viewMatrix将移动信息记录下来。

5.1.三、投影矩阵

这是咱们以前介绍过的了,咱们用projectMatrix记录。

5.1.四、应用矩阵

而后,咱们编写顶点着色器:

1

gl_Position = position * modelMatrix * viewMatrix * projectionMatrix;

这样,咱们就在GPU中,将最终顶点位置计算出来了。
实际上,上面全部步骤,three.js都帮咱们完成了。

5.二、片元着色器处理流程

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

5.三、three.js完整运行流程:

当咱们选择材质后,three.js会根据咱们所选的材质,选择对应的顶点着色器和片元着色器。
three.js中已经内置了咱们经常使用着色器。

全文完。
原文连接
做者:万技师
出处:http://www.cnblogs.com/wanbo/

相关文章
相关标签/搜索