在上一篇文章中,我們就學(xué)習(xí)過(guò)二維矩陣是如何進(jìn)行工作的。我們談到的平移,旋轉(zhuǎn),縮放,甚至像素到剪輯空間的投影都可以通過(guò)一個(gè)矩陣和一些神奇的矩陣數(shù)學(xué)來(lái)完成。做三維只是一個(gè)從那里向前的一小步。
在我們以前的二維的例子中,我們有二維點(diǎn)(x,y),我們乘以一個(gè) 3x3 的矩陣。做三維我們需要三維點(diǎn)(x,y,z)和一個(gè) 4x4 矩陣。
讓我們看最后一個(gè)例子,把它改為三維,我們將再次使用一個(gè) F,但這一次的三維 'F'。
我們需要做的第一件事就是改變頂點(diǎn)著色來(lái)處理三維,這里是舊的著色。
<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>
它甚至更簡(jiǎn)單!
然后我們需要提供三維數(shù)據(jù)。
...
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);
}
接下來(lái),我們需要把所有的矩陣函數(shù)從二維變到三維
這是 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,
];
}
注意,我們現(xiàn)在有3個(gè)旋轉(zhuǎn)函數(shù)。在二維中我們只需要一個(gè)旋轉(zhuǎn)函數(shù),因?yàn)槲覀冎恍枰@ Z 軸旋轉(zhuǎn)?,F(xiàn)在雖然做三維我們也希望能夠繞 X 軸和 Y 軸旋轉(zhuǎn)。你可以從中看出,它們都非常相似。如果我們讓它們工作,你會(huì)看到它們像以前一樣簡(jiǎn)化:
Z 旋轉(zhuǎn)
newX = x * c + y * s;
更多建議: