WebGL著色器

著色器是在GPU上運行的程式。著色器寫入OpenGL ES著色語言(稱為ES SL)。 ES SL擁有它自己的數據類型,限定符,內置的輸入和輸出變數。

數據類型

下表列出了OpenGL ES SL提供的基本數據類型。
S.No. 類型 描述
1 void
表示一個空值
2 bool
接受true或false
3 int
這是一個有符號整數數據類型
4 float
這是一個浮點標量數據類型
5 vec2, vec3, vec4
正分量浮點向量
6 bvec2, bvec3, bvec4
布爾向量
7 ivec2, ivec3, ivec4
有符號整數向量
8 mat2, mat3, mat4 2x2, 3x3, 4x4 浮點矩陣
9 sampler2D
訪問2D紋理
10 samplerCube
訪問立方體映射紋理

修飾符

在 OpenGL ES SL 有三大修飾符 -
S.No.
修飾符
描述
1 attribute
這個修飾符充當每個頂點數據的頂點著色器和OpenGL ES之間的鏈接。此頂點著色器屬性的值在每次執行時變化
2 uniform
這修飾符鏈接著色器程式及其WebGL的應用程式。不同屬性修飾詞,制服(uniforms)的值不會改變。制服(uniforms)是只讀的; 可以用它們與任何基本數據類型來聲明一個變數。
示例 - 統一 vec4 光的位置;
3 varying
這個修飾符形成頂點著色器的內插數據和片段著色器之間的聯繫。它可用於下列數據類型- float, vec2, vec3, vec4, mat2, mat3, mat4, 或數組。
示例 - 改變VEC3正常;

頂點著色器

頂點著色器是一個程式代碼,這被稱為在每個頂點。它改變(移動)的幾何形狀(例如:三角形)從一個地方到另一個。它處理每個頂點的數據(每個頂點的數據),例如頂點座標,法線,色彩,和紋理座標。
在頂點著色器的ES GL代碼,程式員必須定義的屬性來處理數據。這些屬性指向一個頂點緩衝區對象是用JavaScript編寫的。下麵的任務可以使用頂點著色器與頂點變換進行 -
  • 頂點變換
  • 正常轉化和正常化
  • 紋理座標生成
  • 紋理座標變換
  • 光線
  • 彩色材料應用

預定義變數

OpenGL ES SL提供了頂點著色器下麵的預定義變數 -
S.No. 變數 描述
1 highp vec4 gl_Position;
保存頂點的位置
2 mediump float gl_PointSize;
保存變換點的大小。變數的單位是像素

示例代碼

下麵我們來看看頂點著色器的示例代碼。它處理一個三角形的頂點。
attribute vec2 coordinates;

void main(void) {
   gl_Position = vec4(coordinates, 0.0, 1.0);
};
如果你仔細觀察上面的代碼,我們已經聲明屬性變數名稱座標。(此變數將使用getAttribLocation()方法, 屬性的座標被作為參數傳遞給該方法帶著色器程式對象的頂點緩存對象相關聯。)
在給定的頂點著色器程式的第二步驟,gl_position 變數被定義。

gl_Position

gl_Position 僅在頂點著色器程式的預定義變數。它包含的頂點位置。在上面的代碼,座標屬性是通過在一個載體形式。作為頂點著色器是一個每頂點操作,為每個頂點計算 gl_Position 值。
之後,gl_position 值用於由原始組件,剪裁,剔除,以及其他有關的原語操作後的頂點處理是通過固定的功能操作。
我們可以寫頂點著色器的所有可能的操作,我們將在本教學中單獨討論頂點著色器程式。

片段著色器

網狀由多個三角形形成,而每個三角形的表面被稱為一個片段。片段著色器是在每個片段上的每個像素上運行代碼。這是寫入計算並填補單個像素的顏色。下麵的任務可以使用片段著色來進行-
  • 在插值操作
  • 紋理訪問
  • 紋理應用
  • 灰蒙
  • 顏色總和

預定義變數

OpenGL ES SL提供了片段著色器如下面的預定義變數-
S.No. 變數 描述
1 mediump vec4 gl_FragCoord;
保存幀緩衝器中的片段位置
2 bool gl_FrontFacing;
存放屬於一個前置原語的片段
3 mediump vec2 gl_PointCoord;
存放在一個點(點僅光柵化)片段的位置
4 mediump vec4 gl_FragColor;
保存著色器的輸出片段的顏色值
5 mediump vec4 gl_FragData[n]
持有該片段顏色的色彩附件n

示例代碼

片段著色器的下麵的代碼示例演示如何將著色到三角形的每一個像素。
void main(void) {
   gl_FragColor = vec4(0, 0.8, 0, 1);
}
在上面的代碼中,顏色值存儲在變數gl.FragColor。片段著色器程式傳遞的輸出以使用固定函數變數的管道; FragColor就是其中之一。這個變數保存了該模型的像素的顏色值。

存儲和編譯著色器程式

由於著色器是獨立的程式,我們可以把它們作為一個單獨的腳本,並在應用程式中使用。或者也可以直接將它們保存在字串格式,如下圖所示。
var vertCode =
   'attribute vec2 coordinates;' +

   'void main(void) {' +
      ' gl_Position = vec4(coordinates, 0.0, 1.0);' +
   '}';

編譯著色器

編譯包括以下三個步驟: -
  • 創建Shader對象
  • 所述源代碼以創建著色器對象
  • 編譯程序

創建頂點著色器

要創建一個空的著色器,WebGL提供了一個名為createShader()的方法。它創建並返回著色器對象。它的語法如下-
Object createShader (enum type)
如觀察到的語法,該方法接受預定義的枚舉值作為參數。我們有兩種選擇這一點 -
  • gl.VERTEX_SHADER創建頂點著色器

  • gl.FRAGMENT_SHADER 創建片段著色器。

附加源到Shader

可以使用Shader對象 shaderSource ()方法創建源代碼附加。它的語法如下 -
void shaderSource(Object shader, string source)
此方法接受兩個參數 -
  • shader − 必須創建Shader對象傳遞作為一個參數。

  • Source − 必須以字串格式傳入著色器程式代碼。

編譯程序

要編譯程序,必須使用 compileShader()方法。它的語法如下 -
compileShader(Object shader)
這個方法接受著色器程式對象作為參數。創建著色器程式對象之後,附加源代碼,將對象傳遞給該方法。
下麵的代碼片段展示了如何創建和編譯一個頂點著色器和片段著色器來創建一個三角形。
// Vertex Shader
var vertCode =
   'attribute vec3 coordinates;' +

   'void main(void) {' +
      ' gl_Position = vec4(coordinates, 1.0);' +
   '}';

var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);

// Fragment Shader
var fragCode =
   'void main(void) {' +
      ' gl_FragColor = vec4(0, 0.8, 0, 1);' +
   '}';

var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);

合併程式

創建和編譯兩個著色器程式後,你需要創建一個合併的程式同時包含著色器(頂點和片段)。下麵的步驟必須遵循 -
  • 創建一個程式對象
  • 附加兩個著色器
  • 連接兩個著色器
  • 使用程式

創建一個程式對象

通過使用 createProgram()方法創建程式對象。它會返回一個空的程式對象。下麵是它的語法-
createProgram();

附加著色器

附加的著色器的使用 attachShader()方法創建的程式對象。它的語法如下-
attachShader(Object program, Object shader);
此方法接受兩個參數 -
  • Program − 通過創建空的程式對象作為一個參數

  • Shader − 傳遞的著色器編譯程序中的一個(頂點著色器,片段著色器)

注 - 需要附加兩者都使用這種方法的著色器。

鏈接著色器

使用linkProgram()方法鏈接著色器。通過傳遞到所附加的著色器程式對象。它的語法如下-
linkProgram(shaderProgram);

使用程式

WebGL提供了一個名為useProgram()方法。需要鏈接程式時向它傳遞。它的語法如下 -
useProgram(shaderProgram);
下麵的代碼片段展示了如何創建,連接和使用組合著色器程式。
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram); 

上一篇: WebGL幾何體 下一篇: WebGL關聯屬性和緩沖區對象