着色器是在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);