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编程指南》