移动、旋转
对图形进行平移、旋转和缩放,
这样的操作称为 变换(transformations),
或 仿射变换(affine transformations)
平移
问题描述
将点 p(x,y,z) 平移到 p’(x’,y’,z’),
在X轴、Y轴、Z轴三个方向平移的距离分别为:Tx,Ty, Tz ,
其中 Tz=0 。
等式
x’ = x + Tx
y’ = y + Ty
z’ = z + Tz
图解
着色器
平移是一个 逐顶点操作(per-vertex operation),
因此修改应当发生在 顶点着色器 。
Translated Triangle
1 |
|
1 | // 顶点着色器 |
gl.uniform4f() 需要接收 齐次坐标,
齐次坐标共有 4个分量,
最后一个分量如果是 1.0, 表示前三个分量是 一个点的三维坐标。
旋转
- 旋转轴
- 旋转方向
- 旋转角度
也称 正旋转,
判断标准就是:右手握拳,拇指朝上指向z轴正方向,其余四指指向的方向就是旋转的正方向。
问题描述
点 p(x,y,z) 旋转 β 角度之后变为了点 p’(x’,y’,z’),
旋转是绕Z轴逆时针进行的。
旋转等式
设 o 为原点
设 r = op
设 α 为 op 与 x轴夹角
x’ = rcos( α + β ) = r(cosαcosβ - sinαsinβ) = xcosβ - ysinβ
y’ = rsin( α + β ) = r(sinαcosβ + sinβcosα) = ycosβ + xsinβ
z’ = z
图解
着色器
依旧是由顶点着色器处理。
Rotated Triangle
1 |
|
1 | let VSHADER_SOURCE = |
关于uniform变量值的计算位置问题
一般将uniform变量放在JS中算好再传递到shader中,
这样只需要计算一次,效率更高。
点操作符访问分量问题
在shader程序中,
无论是对 传入的变量 还是 gl变量,
都使用 点操作符 来访问分量。
弧度制参数问题
JS内置函数 Math.sin() 和 Math.cos()
都只接受 弧度制参数。
因此需要将 角度值参数 转换为 弧度制参数:
let radian = Math.PI * ANGLE / 180.0 ;
使用数组传入三角函数值
1 | let VSHADER_SOURCE = |
1 | let u_CosBSinB = gl.getUniformLocation(gl.program, 'u_CosBSinB'); |
1 | gl.uniform1f(u_sinB, Math.sin(currentAngle*Math.PI/180.0)); |