學過線性代數(shù)的同學都知道模型的變換包括平移碍扔、旋轉(zhuǎn)涨缚、縮放都可以通過矩陣的運算來表示轮傍。用于變換的矩陣稱為 Model Matrix暂雹。
看一個例子,將圖中三角形先向右平移 0.5金麸, 再繞 Z 軸旋轉(zhuǎn) 60度
矩陣的運算使用了作者寫的 cuon-mattrix.js 這個庫
<script src="lib/cuon-matrix.js"></script>
// vertex shader
var VERTEX_SHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'uniform mat4 u_ModelMatrix;\n' +
'void main() {\n' +
' gl_Position = u_ModelMatrix * a_Position;\n' +
'}\n';
// fragment shader
var FRAGMENT_SHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n' +
'}\n';
var canvas = document.getElementById("canvas");
var gl = canvas.getContext('webgl');
if (!initShaders(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)) {
alert('Failed to init shaders');
}
var vertices = new Float32Array([
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
]);
initVertexBuffers(gl, vertices);
var modelMatrix = new Matrix4();
// <model matrix> = <rotation matrix> * <translation matrix>
modelMatrix.setRotate(60, 0, 0, 1); // (0,0,1) 表示繞 Z 軸旋轉(zhuǎn)
modelMatrix.translate(0.5, 0, 0);
var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);
- uniform mat4 u_ModelMatrix
mat4 是一個 4*4 的矩陣
- gl_Position = u_ModelMatrix * a_Position
計算出變換矩陣乘以 a_Position
- var modelMatrix = new Matrix4();
// <model matrix> = <rotation matrix> * <translation matrix>
modelMatrix.setRotate(60, 0, 0, 1);
modelMatrix.translate(0.5, 0, 0);
先向右平移得到 :
<model matrix> = <translation matrix> * <origin>
再繞 Z 軸旋轉(zhuǎn) 60度得到 :
<model matrix> = <rotation matrix> *(<translation matrix> * <origin>) = (<rotation matrix> * <translation matrix>) * <origin>
先 setRotate 再調(diào)用 translate 就是用矩陣里面已經(jīng)保存的旋轉(zhuǎn)矩陣的值再乘以新計算出來的平移矩陣的值
矩陣乘法滿足結(jié)合律但不滿足交換律擎析,所以先平移再旋轉(zhuǎn)和先旋轉(zhuǎn)再平移是不一樣的。
- gl.uniformMatrix4fv(location, transpose, array)
transpose: 是否轉(zhuǎn)置,webgl 中必須為 false
array: 是 column major order (列優(yōu)先) 數(shù)組
這里通過 modelMatrix.elements 得到矩陣對應的數(shù)組
webgl 中矩陣數(shù)組是以列序排列的揍魂,什么是列序呢桨醋?假設一個矩陣數(shù)組是 [a, e, i, m, b, f, j, n, c, g, k, o, d, h, l, p], 那么它對應的矩陣是下面這樣的
練習:
- 實現(xiàn)三角形先繞 Z 軸旋轉(zhuǎn) 60度再向右平移 0.5 看看是什么效果
思考:
- 有興趣的同學手動計算一下旋轉(zhuǎn)矩陣和平移矩陣和變換矩陣现斋,看看跟庫函數(shù)計算出的是否一樣喜最,可通過 Matrix4 對象的 elements 屬性得到矩陣數(shù)組,另外注意矩陣數(shù)組是列優(yōu)先的庄蹋。