WebGL 2D 圖像轉(zhuǎn)換

2018-10-03 11:21 更新

WebGL 2D 圖像轉(zhuǎn)換

在學(xué)習(xí) 3D 相關(guān)知識(shí)之前,請(qǐng)首先看看 2D 的知識(shí)。請(qǐng)保持耐心。這篇文章某些人看起來可能非常簡(jiǎn)單,但是我們將要講解的知識(shí)是建立在前幾篇的文章的基礎(chǔ)之上。如果你沒有閱讀過,我建議你至少閱讀第一章之后再回到這里繼續(xù)學(xué)習(xí)。

Translation 指的是一些奇特的數(shù)學(xué)名稱,它的基本意思是“移動(dòng)”某物。它同樣適用于將一個(gè)句子從英文“移動(dòng)”成為日語這一說法,但是此處我們談?wù)摰氖菐缀沃械囊苿?dòng)。通過使用以 the first post 結(jié)尾的代碼,你可以僅僅通過修改 setRectangle 距離右邊的的值來使矩形移動(dòng)。如下是一個(gè)基于我們初始示例的代碼:

  // First lets make some variables 
  // to hold the translation of the rectangle
  var translation = [0, 0];

  // then let's make a function to
  // re-draw everything. We can call this
  // function after we update the translation.

  // Draw a the scene.
  function drawScene() {
    // Clear the canvas.
    gl.clear(gl.COLOR_BUFFER_BIT);

    // Setup a rectangle
    setRectangle(gl, translation[0], translation[1], width, height);

    // Draw the rectangle.
    gl.drawArrays(gl.TRIANGLES, 0, 6);
  }

在上面的例子中,我在界面中放置了兩個(gè)可滑動(dòng)欄,你可以通過滑動(dòng)按鈕來修改 translation[0] 和 translation[1] 的值,而且在這個(gè)兩個(gè)值發(fā)生修改時(shí)調(diào)用 drawScene 函數(shù)對(duì)界面進(jìn)行更新。拖動(dòng)滑動(dòng)條對(duì)矩陣進(jìn)行移動(dòng)。

到此處你已經(jīng)覺得很不錯(cuò)。然而,現(xiàn)在假設(shè)我們想要利用相同的操作,但是處理更復(fù)雜的圖形,那么該如何實(shí)現(xiàn)了。

假設(shè)我們想要畫一個(gè)包含 6 個(gè)三角形的 'F' 形狀,如下所示:

F

如下是我們將要使用的改變 setRectangle 值的代碼:

// Fill the buffer with the values that define a letter 'F'.
function setGeometry(gl, x, y) {
  var width = 100;
  var height = 150;
  var thickness = 30;
  gl.bufferData(
      gl.ARRAY_BUFFER,
      new Float32Array([
          // left column
          x, y,
          x + thickness, y,
          x, y + height,
          x, y + height,
          x + thickness, y,
          x + thickness, y + height,

          // top rung
          x + thickness, y,
          x + width, y,
          x + thickness, y + thickness,
          x + thickness, y + thickness,
          x + width, y,
          x + width, y + thickness,

          // middle rung
          x + thickness, y + thickness * 2,
          x + width * 2 / 3, y + thickness * 2,
          x + thickness, y + thickness * 3,
          x + thickness, y + thickness * 3,
          x + width * 2 / 3, y + thickness * 2,
          x + width * 2 / 3, y + thickness * 3]),
      gl.STATIC_DRAW);
}

你會(huì)發(fā)現(xiàn)畫出來的圖形伸縮比例不是很好。如果你想畫出有幾百或者幾千條線組成的幾何圖形,我們就需要編寫一些相當(dāng)復(fù)雜的代碼。在上面的代碼中,每次用 JavaScript 就需要更新所有的點(diǎn)。

有一種更簡(jiǎn)單的方式。僅僅只需要更新幾何圖形,接著修改渲染器部分。

如下是渲染器部分:

<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;

uniform vec2 u_resolution;
uniform vec2 u_translation;

void main() {
   // Add in the translation.
   vec2 position = a_position + u_translation;

   // convert the rectangle from pixels to 0.0 to 1.0
   vec2 zeroToOne = position / u_resolution;
   ...

接著我們將會(huì)稍微重構(gòu)下代碼。我們僅僅需要設(shè)置幾何圖形一次。

// 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,
          30, 0,
          0, 150,
          0, 150,
          30, 0,
          30, 150,

          // top rung
          30, 0,
          100, 0,
          30, 30,
          30, 30,
          100, 0,
          100, 30,

          // middle rung
          30, 60,
          67, 60,
          30, 90,
          30, 90,
          67, 60,
          67, 90]),
      gl.STATIC_DRAW);
}

在實(shí)現(xiàn)我們想要的移動(dòng)之前需要更新下 u_translation 變量的值。

  ...
  var translationLocation = gl.getUniformLocation(
             program, "u_translation");
  ...
  // Set Geometry.
  setGeometry(gl);
  ..
  // Draw scene.
  function drawScene() {
    // Clear the canvas.
    gl.clear(gl.COLOR_BUFFER_BIT);

    // Set the translation.
    gl.uniform2fv(translationLocation, translation);

    // Draw the rectangle.
    gl.drawArrays(gl.TRIANGLES, 0, 18);
  }

注意 setGeometry 只是被調(diào)用一次。在 drawScene 中不需要。

如下是一個(gè)示例。同樣,你可以通過拖動(dòng)滑動(dòng)條來更新圖形的位置。

現(xiàn)在,當(dāng)我們繪制 WebGL 圖像就包括要實(shí)現(xiàn)上面所有的事。我們所作的所有事指的是設(shè)置移動(dòng)變量接著調(diào)用函數(shù)進(jìn)行繪制。即使我們的幾何圖形包含成千上萬的點(diǎn),main 代碼仍然是相同的。

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

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)