WebGL 3D 正交
WebGL 正交 3D
在上一篇文章中,我们就学习过二维矩阵是如何进行工作的。我们谈到的平移,旋转,缩放,甚至像素到剪辑空间的投影都可以通过一个矩阵和一些神奇的矩阵数学来完成。做三维只是一个从那里向前的一小步。
在我们以前的二维的例子中,我们有二维点(x,y),我们乘以一个 3x3 的矩阵。做三维我们需要三维点(x,y,z)和一个 4x4 矩阵。
让我们看最后一个例子,把它改为三维,我们将再次使用一个 F,但这一次的三维 'F'。
我们需要做的第一件事就是改变顶点着色来处理三维,这里是旧的着色。
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;
uniform mat3 u_matrix;
void main() {
// Multiply the position by the matrix.
gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1);
}
</script>
下面是新的
<script id="3d-vertex-shader" type="x-shader/x-vertex">
attribute vec4 a_position;
uniform mat4 u_matrix;
void main() {
// Multiply the position by the matrix.
gl_Position = u_matrix * a_position;
}
</script>
它甚至更简单!
然后我们需要提供三维数据。
...
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
...
// Fill the buffer with the values that define a letter 'F'.
function setGeometry(gl) {
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
// left column
0, 0, 0,
30, 0, 0,
0, 150, 0,
0, 150, 0,
30, 0, 0,
30, 150, 0,
// top rung
30, 0, 0,
100, 0, 0,
30, 30, 0,
30, 30, 0,
100, 0, 0,
100, 30, 0,
// middle rung
30, 60, 0,
67, 60, 0,
30, 90, 0,
30, 90, 0,
67, 60, 0,
67, 90, 0]),
gl.STATIC_DRAW);
}
接下来,我们需要把所有的矩阵函数从二维变到三维
这是 maketranslation,makerotation 和makescale 的二维(前面的)版本
function makeTranslation(tx, ty) {
return [
1, 0, 0,
0, 1, 0,
tx, ty, 1
];
}
function makeRotation(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
c,-s, 0,
s, c, 0,
0, 0, 1
];
}
function makeScale(sx, sy) {
return [
sx, 0, 0,
0, sy, 0,
0, 0, 1
];
}
这是更新的三维版本。
function makeTranslation(tx, ty, tz) {
return [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
tx, ty, tz, 1
];
}
function makeXRotation(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
1, 0, 0, 0,
0, c, s, 0,
0, -s, c, 0,
0, 0, 0, 1
];
};
function makeYRotation(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
c, 0, -s, 0,
0, 1, 0, 0,
s, 0, c, 0,
0, 0, 0, 1
];
};
function makeZRotation(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
c, s, 0, 0,
-s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
];
}
function makeScale(sx, sy, sz) {
return [
sx, 0, 0, 0,
0, sy, 0, 0,
0, 0, sz, 0,
0, 0, 0, 1,
];
}
注意,我们现在有3个旋转函数。在二维中我们只需要一个旋转函数,因为我们只需要绕 Z 轴旋转。现在虽然做三维我们也希望能够绕 X 轴和 Y 轴旋转。你可以从中看出,它们都非常相似。如果我们让它们工作,你会看到它们像以前一样简化:
Z 旋转
newX = x * c + y * s;