我们学会了绘制简单的点和三角形,然而想要绘制生动灵活的动画,平移、旋转、缩放等基本的图片变换是最基础的也是最重要的操作。本节学习三种基本变换的基础要素和公式。
一、平移(逐顶点操作)
(一)公式
x1 = x + Tx
y1 = y + Ty
z1 = z + Tz
(二)关键代码
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'uniform vec4 u_Translation;\n' +
'void main() {\n' +
#相加之后gl_Position第四分量必须为1.0
#a_Position第四分量为1.0,所以u_Translation第四分量为0.0
' gl_Position = a_Position + u_Translation;\n' +
'}\n';
var Tx = 0.5, Ty = 0.5, Tz = 0.0;
function main() {
···
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to intialize shaders.');
return;
}
var n = initVertexBuffers(gl);
#获取u_Translation变量的存储地址
var u_Translation = gl.getUniformLocation(gl.program, 'u_Translation');
#向u_Translation变量赋值
gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, n);
}
(三)每次执行顶点着色器进行的步骤
(1) 将顶点坐标传给a_Position
(2) a_Position + u_Translation
(3) 赋值给gl_Position
二、旋转
正旋转:逆时针方向(右手法则旋转)
描述旋转:
(1)旋转轴
(2)旋转方向
(3)旋转角度
(一)公式
x1 = xcosβ - ysinβ
y1 = xsinβ + ycasβ
z1 = z
(二)关键代码
var VSHADER_SOURCE =
# x' = x cosβ - y sinβ
# y' = x sinβ + y cosβ
# z' = z
'attribute vec4 a_Position;\n' +
'uniform float u_CosB, u_SinB;\n' +
'void main() {\n' +
' gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB;\n' +
' gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB;\n' +
' gl_Position.z = a_Position.z;\n' +
' gl_Position.w = 1.0;\n' +
'}\n';
var ANGLE = 90.0;
function main() {
···
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to intialize shaders.');
return;
}
var n = initVertexBuffers(gl);
#度数转换为角度
var radian = Math.PI * ANGLE / 180.0;
var cosB = Math.cos(radian);
var sinB = Math.sin(radian);
#获取变量地址
var u_CosB = gl.getUniformLocation(gl.program, 'u_CosB');
var u_SinB = gl.getUniformLocation(gl.program, 'u_SinB');
#向变量赋值
gl.uniform1f(u_CosB, cosB);
gl.uniform1f(u_SinB, sinB);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, n);
}
优化
(1) uniform vec4 u_cosBsinB (2) gl.uniform2f(u_cosBsinB, cosB, sinB) (3) 使用u_cosBsinB.x, u_cosBsinB.y访问
三、缩放
公式
x1 = Sx * x
y1 = Sy * y
z1 = Sz * z