GLSL全称为OpenGL Shading Language,是为了实现着色器的功能而向开发人员提供的一种开发语言,对其只要能理解到这个层次就可以了。
每个shader只处理一个像素单元
GLSL的修饰符与基本数据类型
修饰符
-
const:用于声明非可写的编译时常量变量。
-
attribute:用于经常更改的信息,只能在顶点着色器中使用。
-
uniform:用于不经常更改的信息,可用于顶点着色器和片元着色器。
-
varying:用于修饰从顶点着色器向片元着色器传递的变量。
这个修饰符修饰的变量均用于在Vertex Shader和Fragment Shader之间传递参数。首先在顶点着色器中声明这个类型的变量代表纹理的坐标点,并且对这个变量进行赋值,代码如下:
attribute vec2 texcoord; varying vec2 v_texcoord; void main(void) { // 计算顶点坐标 v_texcoord = texcoord; }紧接着在Fragment Shader中也声明同名的变量,然后使用texture2D方法取出二维纹理中该纹理坐标点上的纹理像素值,代码如下(GLSL代码):
varying vec2 v_texcoord; vec4 texel = texture2D(texSampler, v_texcoord);取出了该坐标点上的像素值之后,就可以进行像素变化操作了,比如说提高对比度,最终将改变的像素值赋值给gl_FragColor。
基本数据类型
int、float、bool,这些与C语言都是一致的,需要强调的一点就是,这里面的float是有一个修饰符的,即可以指定精度。三种修饰符的范围(范围一般视显卡而定)和应用情况具体如下。
- highp:32bit,一般用于顶点坐标(vertex Coordinate)。
- medium:16bit,一般用于纹理坐标(texture Coordinate)。
- lowp:8bit,一般用于颜色表示(color)。
向量类型
向量类型是Shader中非常重要的一个数据类型,在做数据传递的时候需要经常传递多个参数,相较于写多个基本数据类型,使用向量类型是非常好的选择
声明方式如下(GLSL代码):
attribute vec4 position;//vec4表示四维向量
矩阵类型
矩阵类型在Shader的语法中也是一个非常重要的类型,有一些效果器需要开发者传入矩阵类型的数据,比如后面会接触到的怀旧效果器,就需要传入一个矩阵来改变原始的像素数据。声明方式如下(GLSL代码):
uniform lowp mat4 colorMatrix;//mat4表示4x4的浮点矩阵
纹理类型
一般仅在Fragment Shader中使用这个类型,二维纹理的声明方式如下(GLSL代码):
uniform sampler2D texSampler;
当客户端接收到这个句柄时,就可以为它绑定一个纹理,代码如下(客户端代码): glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texId); glUniform1i(mGLUniformTexture, 0); 注意上述代码中第一行激活的是哪一个纹理句柄,第三行代码中的第二个参数需要传递对应的Index,就像代码中激活的纹理句柄是GL_TEXTURE0,对应的Index就是0,如果激活的纹理句柄是GL_TEXTURE1,那么对应的Index就是1
GLSL的内置函数与内置变量
内置变量
Vertex Shader的内置变量:
- vec4 gl_position:用来设置顶点转换到屏幕坐标的位置,Vertex Shader一定要去更新这个数值。
- float gl_pointSize:在粒子效果的场景下,需要为粒子设置大小,改变该内置变量的值就是为了设置每一个粒子矩形的大小。
Fragment Shader的内置变量:
vec4 gl_FragColor:用于指定当前纹理坐标所代表的像素点的最终颜色值。
内置函数
- abs(genType x):绝对值函数。
- floor(genType x):向下取整函数。
- ceil(genType x):向上取整函数。
- mod(genType x, genType y):取模函数。
- min(genType x, genType y):取得最小值函数。
- max(genType x, genType y):取得最大值函数。
- clamp(genType x, genType y, genType z):取得中间值函数。
- step(genType edge, genType x):如果x < edge,则返回0.0,否则返回1.0。
- smoothstep(genType edge0, genType edge1, genType x):如果x≤edge0,则返回0.0;如果x≥edge1,则返回1.0;如果edge0 < x < edge1,则执行0~1之间的平滑差值。
- mix(genType x, genType y, genType a):返回线性混合的x和y,用公式表示为:x*(1-a)+y*a,这个函数在mix两个纹理图像的时候非常有用。