WebGL 平移变换
本节课的平移变换在“1.3 WebGL坐标系”源码的基础上更改,以下几种方法都是沿着X轴平移-0.4,也就是把所有顶点X坐标分别加-0.4。下面所谓的几种方法并不是说开发实践中存在的方法,本节课这样安排的目的只是为了通过对比加深你的理解。
方法一
重新定义三角形单个顶点的坐标,这也就是说数学计算任务由人完成。
1.3节中三角形三个顶点的坐标如下。
var data=new Float32Array([
0.0, 0.0, 1.0,//三角形顶点1坐标
0.0, 1.0, 0.0,//三角形顶点2坐标
1.0, 0.0, 0.0//三角形顶点3坐标
]);
1.3节三个顶点的x坐标分别减少0.4,也就实现了整个三角形沿着x轴平移-0.4的效果。
var data=new Float32Array([
-0.4, 0.0, 1.0,//三角形顶点1坐标
-0.4, 1.0, 0.0,//三角形顶点2坐标
0.6, 0.0, 0.0//三角形顶点3坐标
]);
方法二
把下面的代码插入到34行后面,借助for循环
通过下面的一个for循环修改类型数组data=new Float32Array([..
中的顶点数据,javascript代码是在CPU上执行,这也就说把顶点坐标平移的数学计算任务交给CPU处理器
for(var i = 0;i<9;i += 3 )
{
data[i] += -0.4;
}
方法三
使用下面代码把原来的代码gl_Position =vec4(apos.x,apos.y,apos.z,1)
替换掉,着色器语言在GPU上执行,也就是说把顶点平移的数学运算任务交给了GPU。
// 在顶点着色器中逐顶点沿着x轴平移-0.4
gl_Position =vec4(apos.x-0.4,apos.y,apos.z,1);
这句代码涉及到着色器语言知识,apos变量是vec4定义的数据类型,vec4是由四个元素组成的列向量数据结构,可以用点运算符号.
访问,四个分量的名字分别是x、y、z、w,比如apos.x
表示顶点坐标的x分量。
声明数据类型时,vec4
和C语言中的int
、float
用法一样,除此外vec4
也可以当做构造函数来使用,在vec4()
括号里面添加四个参数即可,就像平时调用函数一样,把vec4当做函数名
关于WebGL着色器数据类型的介绍可以查看第二章内容2.3 数据类型-基本类型
、2.4 数据类型-向量
方法四:平移矩阵法
使用矩阵的乘法运算进行三维模型的平移、缩放、旋转、剪切等几何变换,是学习计算机图形必须掌握的内容,用到的数学知识主要是线性代数。如果你的线性代数基础不好,也没有关系,这也正是本课程存在的原因,在下面会通过一个简单的展示让你理解平移矩阵。
在原来的顶点着色器代码中,声明一个4x4矩阵m4
,然后通过矩阵和表示顶点坐标的列向量相乘m4*apos
,实现对顶点apos的平移变换,和方法三一样把数学计算任务交给GPU处理器,具体说是顶点着色器单元(Vertex Processor
),顶点着色器单元能够完成矩阵的乘法运算。
//attribute声明vec4类型变量apos
attribute vec4 apos;
void main() {
//创建平移矩阵(沿x轴平移-0.4)
//1 0 0 -0.4
//0 1 0 0
//0 0 1 0
//0 0 0 1
mat4 m4 = mat4(1,0,0,0, 0,1,0,0, 0,0,1,0, -0.4,0,0,1);
//平移矩阵m4左乘顶点坐标(vec4类型数据可以理解为线性代数中的nx1矩阵,即列向量)
// 逐顶点进行矩阵变换
gl_Position = m4*apos;
}
mat4
关键字和vec4
关键字一样用来声明WebGL着色器变量的数据类型,和vec4
一样也具有构造数据的功能。
vec4
是4x1矩阵,就是列向量,有四个元素,mat4
表示4x4矩阵,mat4()
函数括号中的16个数据,每四个为一组,以列为准,前四个数就是mat4
矩阵的第一列,后面的按顺序依次排列。关于WebGL着色器矩阵的更多介绍,可以查看第二章2.5 数据类型-矩阵
。
平移矩阵解析
下面内容对平移矩阵的讲解,除了需要你知道线性代数这四个字,在此基础上只需要知道矩阵乘法运算的法则就可以了。
如果你学过的线性代数早已忘记,或者不知道为什么一个列向量右乘一个矩阵得到一个新的列向量的计 算过程就是平移的过程,为了降低理解的难度,下面不不采用正向推理讲解,仅仅利用矩阵的乘法法则反向验证。如果你想深入学习可以找一本计算机图形学书籍钻研。
一个点的坐标是(x,y,z)
,假设沿着X、Y、Z轴分别平移Tx、Ty、Tz,毫无疑问平移后的坐标是(x+Tx,y+Ty,z+Tz)
。
请用矩阵的乘法运算法则验证下面矩阵的等式是否成立?
总结
上面计算式的巧妙之处就是把三维坐标,增加一个元素
1.0
,用4x1
矩阵表示,nx1
矩阵也称为列向量,对应的数据类型就是vec4
n维向量增加一个维度用n+1维向量表示就是齐次坐标。
上面的
4x4
矩阵矩阵,就是平移矩阵,平移矩阵左乘顶点的齐次坐标,结果仍然是一个齐次坐标,也就是平移后的坐标。矩阵的乘法满足结合律,如果多次平移,可以把所有的平移矩阵先进行乘法运算,然后左乘要平移顶点的齐次坐标。
通过这个验证计算也可以说明线性代数中的大量定律并不是拍脑门想出来的,是对所有实际问题的高度总结, 这些总结出来的运算法则对于管理学、物理学、工程、机械、计算机等领域都是适用的。就个人经历而言,不管多自由度的机械手设计,还是无人机的飞行控制,还是 计算机图形学涉及到的矩阵变换是没有任何区别的。线性代数基础不好的话,如果想深入学习WebGL,而且时间又比较充足,建议学习完本课程第一章后,重修线性代数,可以把图形学的问题带入到线性代数的学习之中。