首先,將頂點座標傳入着色器,需要遵循以下幾步
- 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
實際上是 幾何圖形裝配階段輸入的數據,注意,集合圖形裝配過程又被稱爲 圖元裝配過程,因爲被裝配的基本圖形 (點,線,面)又被稱爲 圖元,圖元就是圖形的基本元素;
而 片元其實就是像素,那麼顯示在屏幕上的圖形,就是通過將圖形轉換爲 片元,這個過程是 光柵化;
光柵化過程結束後,程序就會 逐片元 的調用片元着色器,也就是說有多少個片元(像素)就會調用多少次片元着色器,每調用一次就處理一個片元,直到最後一個片元被處理後,瀏覽器就會顯示最終的效果;
光柵化 過程中,生成的片元都是帶有座標信息的,調用片元着色器時,這些座標信息也隨着片元傳了進去,因此可以通過片元着色器中的內置變量來訪問片元的座標