WebGL,一项允许开发人员在浏览器里操纵GPU来显示图形的技术。让我们一起走进WebGL的世界。
读者对象
本系列适合具有基础JavaScript知识的开发人员。
准备工作
我们应该在本地搭建好web服务器,或者安装了具有预览功能的IDE。如果你安装了Visual Studio,Nivk童鞋为我们开发了WebGL代码提示功能,你可以通过以下步骤使Visual Studio支持WebGL代码提示:打开Visual Studio——点击工具——点击选项——展开文本编辑器——展开JavaScript——展开IntelliSense——点击引用——切换引用组为Implicit(Web)——将http://www.teajs.net/WebGL-vs-doc.js引用添加到当前组。
此外我们还应该安装了支持WebGL的浏览器,本系列将全部以Chrome为例。
本文的完整示例可以在这里下载(访问密码f6b0)。
本文目标
我们将一边学习WebGL基础知识一边利用所学知识绘制一个六面有着不同颜色的立方体。最后我们将得到一个类似下图的立方体:
理想实验
我们应该如何绘制立方体呢?我们可以在三维空间定义六个顶点,定义顶点间的连接顺序,然后命令GPU按我们给定的点和顺序把图形画出来,并在不同的面涂上不同的颜色。
那我们应该如何定义顶点呢?使用坐标系来定义点已经是常识了。接下来我们来看看如何建立标准的笛卡尔三维坐标系。
WebGL坐标系统
习惯上,我们建立右手坐标系,坐标原点位于画布中央,X轴单位长度为原点到画布右边缘的长度,Y轴单位长度类似。我们会发现X轴的单位长度和Y轴的不一致,这个问题将有之后介绍的投影矩阵来解决。先假设坐标各轴的单位长度相同,我们来定义一下立方体的六个顶点。
顶点坐标
如果立方体中心位于坐标原点并假设边长为2,我们可以得到V0=(1.0,1.0,1.0),V1=(-1.0,1.0,1.0),V2=(-1.0,-1.0,1.0),V3=(1.0,-1.0,1.0),V4=(1.0,1.0,-1.0),V5=(-1.0,1.0,-1.0),V6=(-1.0,-1.0,-1.0),V7=(1.0,-1.0,-1.0)。
如何绘制面
因为WebGL只能绘制三角形(还有点和线),所以为了绘制面V0-V1-V2-V3,我们可以通过绘制三角形V0-V1-V2和三角形V0-V2-V3来拼成面V0-V1-V2-V3。其他面类似。
缠绕顺序
对于三角形V0-V1-V2,我们通过连接V0和V1然后连接V1和V2最后连接V2和V0这种逆时针的缠绕顺序来绘制,也可以通过连接V0和V2然后连接V2和V1最后连接V1和V0这种顺时针的缠绕顺序来绘制。习惯上,我们采用逆时针的缠绕顺序。
如果一个三角形正面各顶点的缠绕顺序为逆时针,那么如果我们站在这个三角形的背面就会感觉各顶点的缠绕顺序为顺时针。
WebGL通过三角形的缠绕顺序来判断正反面。如果我们采用逆时针的缠绕顺序,那么一个面各顶点的缠绕顺序为逆时针为正面,反之为背面。背面是看不到的面,我们可以通过激活WebGL的面剔除功能来剔除背面三角形。
绘制顺序
下面我们来看看这个立方体的各个顶点的绘制顺序,需要注意的是绘制的所有三角形都是逆时针的缠绕顺序。
(从现在开始,三角形V0-V1-V2表示是通过连接V0和V1然后连接V1和V2最后连接V2和V0这种逆时针的缠绕顺序绘制的。)
面V0-V1-V2-V3可通过三角形V0-V1-V2和三角形V0-V2-V3拼成。
面V4-V5-V6-V7可通过三角形V4-V6-V5和三角形V4-V7-V6拼成。(这里要注意一下,面V4-V5-V6-V7的正面是朝向Z轴负方向的,这时候逆时针到底是怎么绕的不易判断。但是这个面的背面是朝向Z轴正方向,也就是说我们站在立方体前望向Z轴负方向,刚好看到的是这个面的背面,所以我们按顺时针的顺序来缠绕,就保证这个面的正面的缠绕顺序为逆时针)
面V4-V5-V1-V0可通过三角形V4-V5-V1和三角形V4-V1-V0拼成。
面V7-V6-V2-V3可通过三角形V7-V2-V6和三角形V7-V3-V2拼成。