WEBGL专栏——图形变换

387 阅读1分钟

在计算机图形学中,一切运算皆矩阵,图形的平移、旋转和缩放都可以表示为图形顶点坐标与相关矩阵的运算。

平移矩阵

[100Tx010Ty001Tz0001][xyz1]=[x+Txy+Tyz+Tz1]\begin{bmatrix} 1 & 0 & 0 & T_x \\ 0 & 1 & 0 & T_y \\ 0 & 0 & 1 & T_z\\ 0 & 0 & 0& 1\end{bmatrix} \begin{bmatrix} x \\ y \\ z\\ 1\end{bmatrix} = \begin{bmatrix} x+T_x \\ y+T_y \\ z+T_z\\ 1\end{bmatrix}

与之对应的着色器语言,如下:

attribute vec4 apos;
void main() {
    //创建平移矩阵(沿x轴平移-0.4)
    //1   0   0  -0.4
    //0   1   0    0
    //0   0   1    0
    //0   0   0    1
    mat4 m4 = mat4(1,0,0,0,  0,1,0,0,  0,0,1,0,  -0.4,0,0,1);
    gl_Position = m4*apos;
}

旋转矩阵

  • 绕x轴旋转
[10000cosθsinθ00sinθcosθ00001][xyz1]=[xycosθzsinθysinθ+zcosθ1]\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta & 0 \\ 0 & \sin\theta & \cos\theta & 0\\ 0 & 0 & 0& 1\end{bmatrix} \begin{bmatrix} x \\ y \\ z\\ 1\end{bmatrix} = \begin{bmatrix} x \\ y\cos\theta-z\sin\theta \\ y\sin\theta+z\cos\theta\\ 1\end{bmatrix}
  • 绕y轴旋转
[cosθ0sinθ00100sinθ0cosθ00001][xyz1]=[zsinθ+xcosθyzcosθxsinθ1]\begin{bmatrix} \cos\theta & 0 & \sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\theta & 0 & \cos\theta & 0\\ 0 & 0 & 0& 1\end{bmatrix} \begin{bmatrix} x \\ y \\ z\\ 1\end{bmatrix} = \begin{bmatrix} z\sin\theta+x\cos\theta \\ y \\ z\cos\theta-x\sin\theta\\ 1\end{bmatrix}
  • 绕z轴旋转
[sinθcosθ00cosθsinθ0000100001][xyz1]=[xcosθysinθxsinθ+ycosθz1]\begin{bmatrix} -\sin\theta & \cos\theta & 0 & 0 \\\cos\theta & \sin\theta & 0 & 0 \\ 0 & 0& 1& 0\\ 0 & 0 & 0& 1\end{bmatrix} \begin{bmatrix} x \\ y \\ z\\ 1\end{bmatrix} = \begin{bmatrix} x\cos\theta-y\sin\theta \\ x\sin\theta+y\cos\theta\\ z\\1\end{bmatrix}

与之对应的着色器语言,如下:

//attribute声明vec4类型变量apos
attribute vec4 apos;
void main() {
    //设置几何体轴旋转角度为30度,并把角度值转化为弧度值
    float radian = radians(30.0);
    //求解旋转角度余弦值
    float cos = cos(radian);
    //求解旋转角度正弦值
    float sin = sin(radian);
    //引用上面的计算数据,创建绕x轴旋转矩阵
    // 1      0       0    0
    // 0   cosα   sinα   0
    // 0  -sinα   cosα   0
    // 0      0        0   1
    mat4 mx = mat4(1,0,0,0,  0,cos,-sin,0,  0,sin,cos,0,  0,0,0,1);
    //引用上面的计算数据,创建绕y轴旋转矩阵
    // cosβ   0   sinβ    0
    //     0   1   0        0
    //-sinβ   0   cosβ    0
    //     0   0   0        1
    mat4 my = mat4(cos,0,-sin,0,  0,1,0,0,  sin,0,cos,0,  0,0,0,1);
    //两个旋转矩阵、顶点齐次坐标连乘
    gl_Position = mx*my*apos;
}

缩放矩阵

[Sx0000Sy0000Sz00001][xyz1]=[xSxySyzSz1]\begin{bmatrix} S_x & 0 & 0 & 0 \\ 0 & S_y & 0 & 0 \\ 0 & 0 & S_z & 0\\ 0 & 0 & 0& 1\end{bmatrix} \begin{bmatrix} x \\ y \\ z\\ 1\end{bmatrix} = \begin{bmatrix} x*S_x \\ y*S_y \\ z*S_z\\ 1\end{bmatrix}

与之对应的着色器语言,如下:

attribute vec4 apos;
void main() {
    //创建缩放矩阵(x缩放0.5)
    //0.5   0   0    0
    //0   1   0    0
    //0   0   1    0
    //0   0   0    1
    mat4 m4 = mat4(0.5,0,0,0,  0,1,0,0,  0,0,1,0,  0,0,0,1);
    gl_Position = m4*apos;
}