WebGL幾何體


所有原語(或物件模型)應該有明確定義的幾何細節。這些細節可以包括頂點,指數,顏色,紋理等。在WebGL中幾何詳細資訊儲存在JavaScript陣列。
圖形物件由其中在GPU上執行的著色器程式來建立。幾何資訊傳遞到使用緩衝區物件著色器程式。

定義所需的幾何體

使用頂點所繪的2D或3D模型被稱為網格。在網格的每個面被稱為多邊形和多邊形是由3個或更多的頂點組成。
要繪製模型在WebGL中渲染,必須定義使用 JavaScript 陣列的頂點和索引。舉例來說,如果我們想建立一個三角形的位於坐標{(5,5),(5,5),(-5,-5)}如圖所示,圖中,那麼可以建立一個陣列的頂點-
var vertices = [
   0.5,0.5,  //Vertex 1
   0.5,-0.5, //Vertex 2
  -0.5,-0.5, //Vertex 3
]; 

同樣,可以建立一個陣列的索引。指數為上述三角形索引將是[0,1,2],可以定義為 -
var indices = [ 0,1,2 ]
為了更好地理解索引,考慮更多複雜的模型,如正方形。我們可以代表一個正方形為一組的兩個三角形。如果(0,3,1)和(3,1,2)是用兩個三角形,我們打算繪製一個正方形,那麼索引將被定義為 -
var indices = [0,3,1,3,1,2];


注意 ?

對於繪圖圖元,WebGL 提供了以下兩種方法 -
  • drawArrays() ? 當使用這種方法,我們通過原語使用JavaScript陣列的頂點。

  • drawElements() ? 當使用這種方法,我們通過這兩個頂點和原語使用JavaScript陣列的索引。

緩衝區物件

緩衝物件是由WebGL的提供了一個機制,用於指示分配到系統中的儲存器區域。在這些緩衝區物件,可以儲存要繪製模型的資料,對應的頂點,索引,顏色等。
使用這些緩衝區物件,可以通過它的屬性變數中的一個傳遞多個資料的著色器程式(頂點著色器)。由於這些緩衝物件駐留在GPU儲存器,它們可以被直接呈現,這反過來又提高了效能。
為了處理幾何形狀,有兩種型別的緩衝區的物件。他們是-
  • 頂點緩衝區物件 (VBO) ? 它保持所述圖形模型,要被渲染的每個頂點的資料。我們使用頂點緩衝物件中的WebGL儲存和處理關於頂點諸如頂點坐標,法線,色彩,紋理坐標資料。

  • 索引緩衝區物件(IBO) ? 它保持所述圖形模型的索引(索引資料),這是要被渲染的。

    限定所需的幾何形狀和它們儲存在JavaScript陣列,需要將這些陣列傳遞給物件緩衝器,資料將被傳遞到著色器程式。下面的步驟是在緩衝器要遵循資料儲存。
  • 建立一個空的緩衝區。
  • 係結相應的陣列物件為空緩衝區。
  • 傳遞資料(頂點/索引)使用型別陣列的一個緩衝區。
  • 取消系結快取(可選)。

註?

WebGL提供了一種特殊型別陣列稱為型別陣列來傳輸資料元素,如索引頂點和紋理。這些型別的陣列儲存大量資料並處理它們在本地二進位制格式,這將產生更好的效能。使用WebGL型別陣列是Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,UInt32Array,Float32Array和Float64Array。
  • 通常,用於儲存頂點資料,我們用Float32Array; 要儲存索引資料,我們使用Uint16Array。
  • 可以建立型別陣列就像使用new關鍵字JavaScript陣列。
現在,讓我們來了解步驟儲存在緩衝區的資料 -

建立緩衝區

要建立一個空的緩衝區物件,WebGL提供了一個名為createBuffer()的方法。該方法如果建立成功,返回一個新建立的緩衝區物件; 否則返回失敗的情況下一個 null 值。
WebGL操作為狀態機。一旦緩衝器被建立,任何後續緩衝操作將在當前緩衝器被執行,直到我們解除系結它。使用下面的程式碼來建立緩衝區 -
var vertex_buffer = gl.createBuffer();

註 ? gl 是參考變數的當前的 WebGL 的上下文。

係結緩衝

建立一個空的緩衝區物件後,需要一個合適的陣列緩衝區(目標)係結到它。 WebGL提供)用於此目的稱為bindBuffer() 方法。

語法

bindBuffer()方法的語法如下 ?

void bindBuffer (enum target, Object buffer)
這個方法有兩個引數,它們將在下面討論。

target ? 第一變數是一個列舉值,表示我們要系結到空緩衝器的緩衝的型別。有兩個預定義列舉值作為該引數選項。他們是-

  • ARRAY_BUFFER  表示頂點的資料。

  • ELEMENT_ARRAY_BUFFER 表示索引資料。

Object buffer ? 第二個是參考變數,在上一步中建立的緩衝區物件。參考變數可以是一個索引快取物件或頂點緩衝物件。

範例

下面的程式碼片段展示了如何使用 bindBuffer()方法。
//vertex buffer
var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

//Index buffer
var Index_Buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

資料傳遞到緩衝區

下一步驟是將資料(頂點/索引)傳送給緩衝器。截至目前資料是一個陣列的形式在傳遞到緩衝區之前,我們需要把它包在WebGL的一個型別陣列。 WebGL提供用於此目的 的 bufferData()方法。

語法

bufferData()方法的語法如下 -
void bufferData (enum target, Object data, enum usage)
這個方法接受三個引數,它們將在下面討論 -

target ? 第一個引數是一個列舉值,表示我們使用了陣列中緩衝的型別。它們可以是ARRAY_BUFFER或ELEMENT_ARRAY_BUFFER。

Object data ? 第二個引數是包含資料寫入到緩衝物件的物件的值。在這裡,我們使用型別陣列來傳遞資料。

Usage ? 該方法的第三個引數是一個列舉變數,來指定如何使用緩衝區物件的資料(儲存的資料)來繪製形狀。有三種選擇此引數如下表所示。

  • gl.STATIC_DRAW ? 資料將指定一次,多次使用。

  • gl.STREAM_DRAW ? 資料將指定一次,使用幾次。

  • gl.DYNAMIC_DRAW ? 資料將被重複指定和多次使用。

範例

下面的程式碼片段展示了如何使用bufferData()方法。假設頂點和指數分別保持在頂點和索引資料的陣列。
//vertex buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

//Index buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

取消系結緩衝區

建議解除系結快取使用後。它可以通過使一個零值代替緩衝物件來完成,如下所示。
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
WebGL提供以下方法來執行緩衝區操作 -
S.No.
方法及說明
1

void bindBuffer (enum target, Object buffer)

target ? ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

2

void bufferData(enum target, long size, enum usage)

target ? ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

usage ? STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW

3

void bufferData (enum target, Object data, enum usage)

target and usage ? Same as for bufferData above

4

void bufferSubData(enum target, long offset, Object data)

target ? ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER

5 Object createBuffer()
6 void deleteBuffer(Object buffer)
7

any getBufferParameter(enum target, enum pname)

target ? ARRAY_BUFFER, ELEMENT_ ARRAY_BUFFER

pname ? BUFFER_SIZE, BUFFER_USAGE

8 bool isBuffer(Object buffer)