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);