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