WebGL - 顏色和紋理

首先,將頂點座標傳入着色器,需要遵循以下幾步

  • 1、創建緩衝區對象;
  • 2、將緩衝區對象綁定到target上;
  • 3、將頂點座標數據寫入緩衝區對象;
  • 4、將緩衝區對象分配給對應得 attribute變量;
  • 5、開啓 attribute變量;

1、非座標數據傳入頂點着色器

所以將多個頂點相關得數據通過傳衝去對象傳入頂點着色器,其實只需要每種數據重複以上步驟即可;

首先,需要再頂點着色器中定義可以接收頂點大小得變量,此處片元着色器和之前一致;

attribute vec4 a_Position;
attribute float a_PointSize;
void main(){
    gl_Position = a_Position;
    gl_PointSize = a_PointSize;
}

然後就需要重複以上5個步驟,將頂點大小數據傳遞給頂點着色器

var sizes = new Float32Array([10.0, 20.0, 30.0]);//此處需要傳遞的單精度浮點

此時,再webgl系統中就存在兩個緩衝區,一個是頂點位置數據,一個事頂點大小數據,因此 通過爲頂點得每種數據建立一個緩衝區,然後分配給對應得 attribute 變量,就可以向頂點着色器傳遞多份逐頂點得數據信息

2、gl.vertexAttribPointer得步進和偏移參數

使用多個緩衝區對象向頂點着色器傳遞多種數據,比較適合數據量不大得情況,但是數據較大就不適合了,但是webgl允許 將頂點得各種信息打包到一個緩衝區對象中;

var verticesSizes = new Float32Array([
    // 兩種數據打包到同一個緩衝區對象中去
    // 頂點位置 和 尺寸數據
    0.0, 0.5, 10.0,  // 第一個點
    0.5, -0.5, 20.0, // 第二個點
    -0.5, -0.5, 30.0 // 第三個點
]);

那麼 webgl怎麼區分裏面得數據那個部分是頂帶你位置和尺寸呢?

因爲Float32Array是類型化數組,可以通過靜態屬性BYTES_PER_ELEMENT獲得數組中每個元素所佔得字節數;

Float32Array 的情況下返回4

詳細請參考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Float32Array

var FSIZE = verticesSize.BYTES_PER_ELEMENT;

1、將位置數據分配給 attribute變量

// 將緩衝區對象分配給attribute變量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 3, 0);

2、將頂點大小數據分配給 attribute變量

gl.vertexAttribPointer(a_PointSize, 1, gl.FLOAT, false, FSIZE * 3, FSIZE * 2);

下面來看下方法gl.vertexAttribPointer(location,size,type,normalize,stride,offset)參數

  • 1、location 待分配的 attribute變量的存儲位置;
  • 2、size 指定緩衝區中,每個頂點的分量個數;
  • 3、type 指定數據格式;
  • 4、normalize true或者false表明是否將非浮點型的數據歸一化到[0,1]或者[-1,1];
  • 5、stride指定兩個頂點間的字節數,默認爲0;
  • 6、offset指定緩衝區對象中的偏移量(以字節爲單位),即attribute變量從緩衝區中的何處開始存儲,若從起始位置,則參數爲0;

再來看下類型化數組中的數據

var verticesSizes = new Float32Array([
    // 兩種數據打包到同一個緩衝區對象中去
    // 頂點位置 和 尺寸數據
    0.0, 0.5, 10.0,  // 第一個點
    0.5, -0.5, 20.0, // 第二個點
    -0.5, -0.5, 30.0 // 第三個點
]);

如果想要獲取每個頂點的數據,參數stride需要是 字節數乘以第一個頂點的數據個數,所以是 SIZE * 3,前三個數據是一個頂點的信息;

但是怎麼區分頂點位置和大小信息呢?

那就需要設置最後一個參數,偏移量參數 offset 距首個元素的偏移距離,從0開始;

頂點位置數據是前兩個數據,因此距離首個元素的偏移距離是 0;

頂點大小數據是每個頂點數據的第三個數據,因此距離首個元素的偏移距離是2;

3、修改頂點顏色

首先,需要了解頂點着色器 如何向 片元着色器傳遞數據;

將頂點着色器中的數據傳遞給片元着色器,需要通過 varying變量, varying變量存在的作用就是,從頂點着色器向片元着色器傳遞數據;

下面來看着色器代碼

1、頂點着色器

attribute vec4 a_Position;
attribute vec4 a_Color; //用於接收外部的頂點顏色信息
varying vec4 v_Color;// 聲明 varying 變量
void main(){
    gl_Position = a_Position;
    gl_PointSize = 10.0;//設置頂點大小
    v_Color = a_Color;//將頂點顏色賦值給varying變量
}

2、片元着色器

precision mediump float; //聲明浮點數精度
void main(){
    gl_FragColor = v_Color;//從頂點着色器接收顏色數據
}

varying 變量只能是 float 類型的

webgl如果頂點着色器與片元着色器中有類型和命名都相同的 varying 變量 那麼頂點着色器賦值給該變量的值就會被自動的傳入片元着色器

所以頂點着色器中的 v_color中的值被傳遞給了,片元着色器中的v_Color變量;

4、幾何形狀的裝配和光柵化

  • 圖形裝配過程:這一步驟的任務是,將孤立的頂點座標裝配成集合圖形,集合圖形的類別是由 gl.drawArrays()方法的第一個參數決定;
  • 光柵化過程:這一步的任何是,將裝配好的集合圖形轉化爲片元;

變量 gl_Position實際上是 幾何圖形裝配階段輸入的數據,注意,集合圖形裝配過程又被稱爲 圖元裝配過程,因爲被裝配的基本圖形 (點,線,面)又被稱爲 圖元,圖元就是圖形的基本元素;

片元其實就是像素,那麼顯示在屏幕上的圖形,就是通過將圖形轉換爲 片元,這個過程是 光柵化

光柵化過程結束後,程序就會 逐片元 的調用片元着色器,也就是說有多少個片元(像素)就會調用多少次片元着色器,每調用一次就處理一個片元,直到最後一個片元被處理後,瀏覽器就會顯示最終的效果;

光柵化 過程中,生成的片元都是帶有座標信息的,調用片元着色器時,這些座標信息也隨着片元傳了進去,因此可以通過片元着色器中的內置變量來訪問片元的座標

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章