GLSL全称是 Graphics Library Shader Language (图形库着色器语言),是着色器使用的语言
注释:
单行注释://
多行注释:/* */
GLSL是一个强类型的语言
变量:
变量的名称可以使用字母,数字以及下划线,但变量名不能以数字开头,还有变量名不能以gl_作为前缀
基本数据类型:
(1)标量:
支持使用浮点数(float)、整数(int)、无符号的整数(uint )和布尔值(bool)
(2)矢量:
浮点数矢量:
vec2 (2个浮点数的矢量)
vec3 (3个浮点数的矢量)
vec4 (4个浮点数的矢量)
整数矢量:
ivec2 (2个整数的矢量)
ivec3 (3个整数的矢量)
ivec4 (4个整数的矢量)
布尔矢量:
bvec2 (2个布尔值的矢量)
bvec3 (3个布尔值的矢量)
bvec4 (4个布尔值的矢量)
内置的矢量可以很方便的存储和操作颜色、位置和纹理坐标等。
矢量的特殊性质包括可以通过字段选择(就像是用结构一样)或者作为数组来访问各个分量。
(3)矩阵:
mat2 (2×2的浮点数矩阵)
mat3 (3×3的浮点数矩阵)
mat4 (4×4的浮点数矩阵)
mat矩阵就像是一个vec数组,它也可以使用数组来进行访问。
(4)取样器:
纹理查找需要指定一个纹理或者纹理单元,GLSL不关心纹理单元的底层实现,它提供了一个简单而不透明的句柄来封装需要查找的对象。这些句柄被称为取样器(SAMPLERS)
sampler1D (访问一个一维纹理)
sampler2D (访问一个二维纹理)
sampler3D (访问一个三维纹理)
samplerCube (访问一个立方贴图纹理)
sampler1DShadow (访问一个带对比的一维深度纹理)
sampler2DShadow (访问一个带对比的二维深度纹理)
只能通过uniform限定的取样器从应用程序接收取样器
eg:
uniform sampler2D texture;
结构体
从逻辑上讲不同的类型的数据组到一个数据集合中
eg:
struct dirlight{
vec3 direction;
vec3 color;
};
数组
GLSL中只可以使用一维的数组。数组的类型可以是一切基本类型或者结构体
数组的下标从0开始。合理的范围是[0, size - 1]
eg:
vec4 lightPositions[8];
[3];
类型修饰符
const:常量
attribute:表示只读的顶点数据,只用在顶点着色器中。数据来自当前的顶点状态或者顶点数组
uniform :一致变量。在着色器执行期间一致变量的值是不变的。与const常量不同的是,这个值在编译时期是未知的是由着色器外部初始化的。一致变量在顶点着色器和片段着色器之间是共享的。它也只能在全局范围进行声明。
varying:顶点着色器的输出。例如颜色或者纹理坐标,(插值后的数据)作为片段着色器的只读输入数据。必须是全局范围声明的全局变量。可以是浮点数类型的标量,向量,矩阵。不能是数组或者结构体。
in:用在函数的参数中,表示这个参数是输入的,在函数中改变这个值,并不会影响对调用的函数产生副作用。(相当于C语言的传值),这个是函数参数默认的修饰符
out:用在函数的参数中,表示该参数是输出参数,值是会改变的。
inout:在函数的参数,表示这个参数即是输入参数也是输出参数。
内置变量:
顶点着色器
名称 | 类型 | 描述 |
gl_Color | vec4 | 输入属性-表示顶点的主颜色 |
gl_SecondaryColor | vec4 | 输入属性-表示顶点的辅助颜色 |
gl_Normal | vec3 | 输入属性-表示顶点的法线值 |
gl_Vertex | vec4 | 输入属性-表示物体空间的顶点位置 |
gl_MultiTexCoordn | vec4 | 输入属性-表示顶点的第n个纹理的坐标 |
gl_FogCoord | float | 输入属性-表示顶点的雾坐标 |
gl_Position | vec4 | 输出属性-变换后的顶点的位置,用于后面的固定的裁剪等操作。所有的顶点着色器都必须写这个值。 |
gl_ClipVertex | vec4 | 输出坐标,用于用户裁剪平面的裁剪 |
gl_PointSize | float | 点的大小 |
gl_FrontColor | vec4 | 正面的主颜色的varying输出 |
gl_BackColor | vec4 | 背面主颜色的varying输出 |
gl_FrontSecondaryColor | vec4 | 正面的辅助颜色的varying输出 |
gl_BackSecondaryColor | vec4 | 背面的辅助颜色的varying输出 |
gl_TexCoord[] | vec4 | 纹理坐标的数组varying输出 |
gl_FogFragCoord | float | 雾坐标的varying输出 |
片段着色器
名称 | 类型 | 描述 |
gl_Color | vec4 | 包含主颜色的插值只读输入 |
gl_SecondaryColor | vec4 | 包含辅助颜色的插值只读输入 |
gl_TexCoord[] | vec4 | 包含纹理坐标数组的插值只读输入 |
gl_FogFragCoord | float | 包含雾坐标的插值只读输入 |
gl_FragCoord | vec4 | 只读输入,窗口的x,y,z和1/w |
gl_FrontFacing | bool | 只读输入,如果是窗口正面图元的一部分,则这个值为true |
gl_PointCoord | vec2 | 点精灵的二维空间坐标范围在(0.0, 0.0)到(1.0, 1.0)之间,仅用于点图元和点精灵开启的情况下。 |
gl_FragData[] | vec4 | 使用glDrawBuffers输出的数据数组。不能与gl_FragColor结合使用。 |
gl_FragColor | vec4 | 输出的颜色用于随后的像素操作 |
gl_FragDepth | float | 输出的深度用于随后的像素操作,如果这个值没有被写,则使用固定功能管线的深度值代替 |
成分选择
向量中单独的成分可以通过{x,y,z,w},{r,g,b,a}或者{s,t,p,q}的记法来表示。
这些不同的记法用于顶点,颜色,纹理坐标。
在成分选择中,你不可以混合使用这些记法。其中{s,t,p,q}中的p替换了纹理的r坐标,因为与颜色r重复了
eg:
vec3 vec = {0.5, 0.35, 0.7};
float r = vec.r;
float myYz = vec.yz;
float myQ = vec.q;//出错,数组越界访问,q代表第四个元素
float myRY = vec.ry; //不合法,混合使用记法
//调换顺序
//重复其中的值
控制流:
与C和C++相似
for, while, do/while的循环方式。使用continue跳入下一次循环,break结束循环
if/else
discard——片段着色器特有的,使用discard会退出片段着色器,不执行后面的片段着色操作。片段也不会写入帧缓冲区。
函数
在每个shader中必须有一个main函数。main函数中的void参数是可选的,但返回值是void时必须的。
函数可以重载,但不允许递归