WebGL動畫有移動、旋轉和縮放,咱們將移動、旋轉和縮放圖形,而後將其繪製到屏幕上,稱爲變換(transformations)或者仿射變換(affine transformations).html
1.移動web
效果圖:編程
1.1在WebGL入門教程(二)-webgl繪製三角形的基礎上進行修改,原理就是,三個頂點的座標(x,y,z)同時發生了變化,從新計算三個座標值;數組
//頂點着色器程序 var VSHADER_SOURCE = "attribute vec4 a_Position;" + "uniform vec4 u_Translation;" + "void main() {" + //設置座標 "gl_Position = a_Position + u_Translation; " + "} ";
從上面能夠看到,頂點增長了一個變量平移距離u_Translation,而後將平移距離傳輸給定點着色器;post
//聲明偏移變量 var Tx = 0.5,Ty = 0.5,Tz = 0.0; //將平移距離傳輸給定點着色器 var u_Translation = gl.getUniformLocation(shaderProgram,'u_Translation'); gl.uniform4f(u_Translation,Tx,Ty,Tz,0.0);
1.2還有一種表達方式,就是用變形矩陣進行計算座標。動畫
通過計算得出平移矩陣公式(這是行主序,可是在寫代碼的時候就是列主序了):webgl
什麼是列主序:url
例如一個座標點 V(x,y,z,w),實際上是以列的形勢存儲的。spa
[x]code
[y]
[z]
[w]
剛纔獲得的公式是行主序的,因此,必定要靈活變通。
得出x'=x+Tx;y'=y+Ty;z'=z+Tz;
由上面的公式就開始寫代碼吧:首先就是頂點着色器的更改,<新座標>=<矩陣>*<舊座標>,得出下面代碼;
var VSHADER_SOURCE = "attribute vec4 a_Position;" + "uniform mat4 u_xformMatarix;" + "void main() {" + //設置座標 "gl_Position = u_xformMatarix * a_Position;" + "} ";
而後將矩陣傳輸給定點着色器;
var Tx = 0.5,Ty = 0.5,Tz = 0.0; //注意WebGL的矩陣式列主序的 var xformMatrix = new Float32Array([ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Tx, Ty, Tz, 1.0 ]);
//而後將矩陣傳輸給定點着色器 var u_xformMatarix = gl.getUniformLocation(shaderProgram,'u_xformMatarix'); gl.uniformMatrix4fv(u_xformMatarix, false, xformMatrix);
uniformMatrix4fv方法參數的講解,
第一個參數:表明uniform變量的存儲位置;
第二個參數:在WebGL中指定爲false;
第三個參數:待傳輸的類型化數組;
2.旋轉
效果圖:
2.1同理,旋轉也須要計算旋轉以後三個座標的值,不過它的要求就高了, 須要知道旋轉軸,旋轉方向和旋轉角度。
這是就須要數學知識了
//頂點着色器程序 var VSHADER_SOURCE = "attribute vec4 a_Position;" + "uniform float u_CosB,u_SinB;" + "void main() {" + //設置座標 "gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB;" + "gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB;" + "gl_Position.z= a_Position.z;" + "gl_Position.w = 1.0;" + "} ";
從上面能夠看到,頂點着色器定義了正弦值,餘弦值,而後根據獲得的值或得座標值,,而後將旋轉圖形所需的數據傳輸給定點着色器
//旋轉角度 var ANGLE = 45.0;
// 將旋轉圖形所需的數據傳輸給定點着色器 var radian = Math.PI*ANGLE/180.0;//轉化爲弧度 var cosB = Math.cos(radian); var sinB = Math.sin(radian); var u_CosB = gl.getUniformLocation(shaderProgram,'u_CosB'); var u_SinB = gl.getUniformLocation(shaderProgram,'u_SinB'); gl.uniform1f(u_CosB,cosB); gl.uniform1f(u_SinB,sinB);
2.2 通過計算得出旋轉矩陣公式(這是行主序,可是在寫代碼的時候就是列主序了):
由上面的公式就開始寫代碼吧:首先就是頂點着色器的更改,<新座標>=<矩陣>*<舊座標>,得出下面代碼;
var VSHADER_SOURCE = "attribute vec4 a_Position;" + "uniform mat4 u_xformMatarix;" + "void main() {" + //設置座標 "gl_Position = u_xformMatarix * a_Position;" + "} ";
而後將矩陣傳輸給定點着色器;
var xformMatrix = new Float32Array([ cosB, sinB, 0.0, 0.0, -sinB, cosB, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ]); var u_xformMatarix = gl.getUniformLocation(shaderProgram,'u_xformMatarix'); gl.uniformMatrix4fv(u_xformMatarix, false, xformMatrix);
3.縮放
效果圖:
直接來看矩陣表示吧,畢竟之後都是用矩陣的,
主須要更改傳輸到頂點時的代碼
var Sx = 1.0;Sy =1.5; Sz = 1.0; var xformMatrix = new Float32Array([ Sx, 0.0, 0.0, 0.0, 0.0, Sy, 0.0, 0.0, 0.0, 0.0, Sz, 0.0, 0.0, 0.0, 0.0, 1.0 ]); var u_xformMatarix = gl.getUniformLocation(shaderProgram,'u_xformMatarix'); gl.uniformMatrix4fv(u_xformMatarix, false, xformMatrix);
*以上摘至《WebGL編程指南》