WebGL 3D 正交

2018-10-03 11:29 更新

WebGL 正交 3D

在上一篇文章中,我們就學(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;

以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)