在三维空间中,点是最基础的图形对象,一系列点构成了面和体等图形,为了真实还原并表达三维空间,往往需要引入相机(模拟人眼)、灯光(模拟光照)等各种辅助对象。
点可以是具体的点图形,也可以表示相机的位置、灯光的位置,其坐标位置用xyz三个数字来表示。坐标、相机和光线是有方向和大小的,可以用一个向量来表示。
在对空间图形进行位置变换(平移、旋转、缩放)、计算光线、颜色、投影的时候,可以使用常规的解方程运算,也可以使用向量和矩阵运算。用代数公式计算相对较复杂,使用矩阵来计算步骤要简单一些,只需要套计主各个变换的矩阵即可。另外,现代CPU、GPU对矩阵乘法都有专门优化,计算效率很高。
在 WebGL 中进行向量和矩阵运算,需要关注其几何意义、物理意义。
具体的数学运算规则在 glsl 语法中结合代码介绍,这里说下概念和常用的运算。
需要特别注意:数学知识很重要。如果在对向量和矩阵的原理和使用方法有了一定了解,在实际开发中遇到了疑难杂症等bug,就可以知道如何去查找原因了。
一、向量是什么
1.1、向量的概念
向量?矢量?这些概念是什么意思呢,有什么用,我们可以从以下三个方面理解:
通用的概念是: 一个有大小和方向的量。
物理学的角度: 有方向和大小的量,比如“光线”、“力”、“速度”、“磁场”这些同时具有方向和大小两个属性。。
编程的角度: 向量只是一列有序的数字,这列数字可以用纵列(column)表示,在代码往往用数组来表示。
数学的角度: 在几何或者代数中,就是指一个坐标或者数值,有长度或者位置信息,体现某个量的特征。
在 WebGL 中通常用向量来表示有方向的坐标,向量可以用一行来表示,也可以用一列来表示,WebGL 中使用的是列向量, 也就是说WebGL中的vec* 对象是列向量 。
1.2、多维向量
向量的元素具有多个,例如表示二维坐标的是二维向量,表示三维坐标久要用三维向量,如果某个物体具有n个属性,那么久要用n维向量来表示。
例如用向量来表示一个“人”的信息:['张三', '男', '23', '中国', '法外狂徒']。
1.3向量运算的意义
加减法
向量 A 和向量 B 进行加法运算得到向量 C,则向量 C 的起点与向量 A 的起点重合,终点为向量 B 的终点。首位相连的向量相加,结果是第一个向量的起点和最后一个向量终点构成的新向量。在 WebGL 中两个方向向量相加,可以计算出这两个向量夹角一般方向上的向量(例如计算光线和视线两个方向向量夹角1/2处的向量)。
向量 A 和向量 B 进行减法运算得到向量 C,则向量 C 的起点为向量 B 的终点,终点为向量 A 的终点。在 WebGL 中两个点坐标的向量相减,可以计算出这两个点构成的的方向向量(例如:计算光源和物体之间的相对方向)。
点乘
也叫内积、数积。两个向量点乘的结果是一个标量,表示这俩向量的夹角余弦值。在 WebGL 中两个单位向量点乘,可以判断他们的相似程度(方向是否一致),-1表示方向相反,0表示互相垂直,1表示方向相同,在 WebGL 中通常用于光线计算。
两个向量的点积可以用来一个向量在另一个向量上的投影长度。其运算法则为:d=|a||b|cosθ,其中|a|和|b|分别是向量a和向量b的大小(模),θ为向量a与向量b之间的夹角(点积)。
向量点乘是一个数字,所以满足交换律。
叉乘
两个向量叉乘的结果是一个新的向量。在 WebGL 中两个单位向量叉乘结果可以用来表示这两向量所在面的法向量。
其运算法则为:向量a×向量b=|a||b|sinθ×n,其中θ为向量a与向量b之间的夹角,n是一个与向量a、向量b所在平面垂直的单位向量。
向量叉乘不满足交换律。
glsl 里的*是向量的叉乘。
二、矩阵是什么
2.1、矩阵的概念
矩阵是一个数字阵列,一个二维数组,m行n列的阵列称为m*n矩阵。行列式相等的矩阵也叫方阵。对角线为1,其他位置都是 0 的矩阵,类似乘法中的1。
在代码中,矩阵往往用一个数组来表示,要根据行主序还是列主序来确认数组的实际排列,WebGL 中的矩阵是列主序的。
例如上图中的矩阵在 Javascript 中用数组表示就是:[1, 4, 2, 5, 3, 6]。
一般用矩阵来表示平移、缩放和旋转变换参数。
2.2、矩阵运算
矩阵加减法
矩阵加减法只能是相同阶的矩阵之间进行,及行列数必须相同。直接用对应位置的数字加减就是新矩阵的结果。
矩阵乘除法
一个m∗n的的 A 矩阵,和一个n∗p的 B 矩阵相乘,将得到一个m∗p的矩阵 C 。
矩阵相乘的前提:第一个矩阵的列数(column)和第二个矩阵的行数(row)相同。
矩阵相乘就是第一个矩阵的 m 行和第二个矩阵的 p 列每一项相乘、求和,形成新矩阵第(m,p)位置的元素。
- 矩阵相乘不满足交换律,乘数和被乘数不能互换!
- 矩阵相乘满足结合律、满足分配律!
- WebGL 里的矩阵乘法是左乘原则。
可以在这个网站体验下矩阵运算:www.bchrt.com/tools/matri…
三、向量和矩阵的运算
3.1、运算规则
列向量可以看成是一个mx1的矩阵,行向量可以看成一个1xn的矩阵,因此他们都可以和矩阵进行相乘。
由矩阵相乘必须满足第一个矩阵的列数等与第二个矩阵的行数这个规则可知:当向量和矩阵相乘时,行向量只能作为乘数,列向量只能作为被乘数。
- 矩阵乘以列向量,相当于矩阵的列向量的线性组合。结果为列向量!
- 行向量乘以矩阵,相当于矩阵的行向量的线性组合。结果为行向量!
在实际运算中,按照数学领域中矩阵相乘的规则:
- 如果是行向量,向量要放在左侧相乘。
- 如果是列向量,向量要放在右侧相乘。WebGL中
mat*和vec*相乘。
3.2、WebGL中的运算
在 WebGL 中,空间变换的运算规则是矩阵*向量。
更多线性代数知识可以参开这里:www.zhihu.com/people/Augu…
这是WebGL 系列的入门文章,免费订阅,如有帮助请点赞收藏,纰漏之处欢迎指正!
也欢迎关注公众号交流知识哇😄