七、移动、旋转、缩放

311 阅读1分钟

我们学会了绘制简单的点和三角形,然而想要绘制生动灵活的动画,平移、旋转、缩放等基本的图片变换是最基础的也是最重要的操作。本节学习三种基本变换的基础要素和公式。

一、平移(逐顶点操作)

(一)公式

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