GLSL是什么
GLSL是OpenGL Shading Language的缩写,意为OpenGL着色语言。
顾名思义是,这是用来在OpenGL中着色编程的语言。GLSL作为一种使用类C语言语法作为基础的高阶着色语言,避免了使用汇编语言或硬件规格语言的复杂性。它的工作环境在图形卡的GPU上。作用是代替了固定的渲染管线的一部分,使渲染管线中不同层次具有了可编程性。比如:视图转换、投影转换等。
GLSL的着色器代码分成2个部分:Vertex Shader(顶点着色器)和Fragment(片断着色器),有时还会有Geometry Shader(几何着色器)。
承接上篇着色器Shader基础,可以了解到负责运行顶点着色的是顶点着色器。它可以得到当前OpenGL中的状态,并由GLSL内置变量进行传递。
GLSL中提供了许多内建的函数方便开发者使用。这些都可以在官方手册中查找。
除了GLSL(Khronos Group协会)还有HLSL(微软公司)以及Cg(英伟达公司)等编程语言,除了Cg因为英伟达的放弃支持而逐步退出。HLSL和GLSL依然是当今活跃的Shader语言。
GLSL基础语法
变量基本类型:
| 类型 | 说明 |
|---|---|
| void | 空类型,即不返回任何值 |
| bool | 布尔类型 |
| int | 带符号的整数 |
| float | 带符号的浮点数 |
| vec2, vec3, vec4 | n维浮点数向量 |
| bvec2, bvec3, bvec4 | n维布尔向量 |
| ivec2, ivec3, ivec4 | n维整数向量 |
| mat2, mat3, mat4 | 2x2, 3x3, 4x4 浮点数矩阵 |
| sampler1D | 一维纹理句柄 |
| sampler2D | 二维纹理句柄 |
| sampler3D | 三维纹理句柄 |
| samplerCube | 盒纹理句柄 |
基本结构和数组:
| 类型 | 说明 |
|---|---|
| 结构 | struct type-name{} 类似c语言中的 结构体 |
| 数组 | float foo[3] 数组可以是结构体的成员 |
结构体注意项:
只有结构体中的每个成分都相等,那么这两个结构体才是相等的。
访问结构体的内部成员使用. (点语法)来访问。
例如:
struct Light{
vec3 position;
vec3 color;
}
Light light0;
vec3 position= light0.position;
vec3 color = light0.color;
结构体至少包含一个成员。固定大小的数组也可以被包含在结构体中。GLSL的结构体不支持嵌套定义。只有预先声明的结构体可以嵌套其中。
struct myStruct {
vec3 points[3]; //固定大小的数组是合法的
surface surf; //可以,之前已经定义了
struct velocity { //不合法float speed;
vec3 direction;
} velo;
subSurface sub; //不合法,没有预先声明;};
struct subSurface {
int id;
} ID;
};
数组注意项:
GLSL只支持1维数组
修饰符:
| 类型 | 说明 | 顶点着色器 | 片元着色器 | 注意点 |
|---|---|---|---|---|
| const | 常量修饰符 | √ | √ | 声明时初始化 |
| attribute | 只读的顶点数据 | √ | x | 必须是全局声明,不能在函数内部,不能是数组或结构体 |
| uniform | 一致变量 | √ | √ | 必须是全局声明,着色器执行时不变,在V/F中共享 |
| varying | 顶点着色器的输出 | √ | √ | 必须是全局声明,值为纹理,颜色,坐标,在V/F间传递数据 |
| in | 表示参数为输入 | √ | √ | 此为函数参数的默认值 |
| out | 用于函数参数 | √ | √ | 表示输出参数,值是会改变的 |
| inout | 用于函数参数 | √ | √ | 表示既为输入也为输出参数 |
修饰符中最重要的是attribute、uniform和varying
uniform 用于从外部给GLSL传递参数
attribute 用来设置每个顶点的数据
varying 用于在顶点着色器和片元着色器之间传递数据。
内置变量
顶点着色器
| 类型 | 说明 | 描述 | |
|---|---|---|---|
| gl_Color | vec4 | 输入 | 表示顶点主颜色 |
| gl_SecondaryColor | vec4 | 输入 | 表示顶点辅助颜色 |
| gl_Normal | vec4 | 输入 | 表示顶点的法线值 |
| gl_Vertex | vec4 | 输出 | 表示物体空间的顶点位置 |
| gl_MultiTexCoordn | vec4 | 输入 | 表示顶点的第n个纹理的坐标 |
| gl_FogCoord | float | 输入 | 表示顶点的雾坐标 |
| gl_Position | vec4 | 输出 | 变换后的顶点位置,所有的顶点着色器必须填写此值 |
| gl_ClipVertex | vec4 | 输入 | 用户裁剪平面 |
| gl_PointSize | float | 输入 | 点的大小 |
| gl_FrontColor | vec4 | 输出 | 正面主颜色的输出 |
| gl_BackColor | vec4 | 输出 | 表示顶点主颜色 |
| gl_FrontSecondaryColor | vec4 | 输出 | 正面辅助颜色的输出 |
| gl_BackSecondaryColor | vec4 | 输出 | 背面辅助颜色的输出 |
| gl_TexCoord[] | vec4 | 输出 | 纹理坐标的数组的输出 |
| gl_FogFragCoord | float | 输出 | 雾坐标的输出 |
| gl_ModelViewMatrix | Mat4 | 输出 | 模型视图变换矩阵 |
| gl_ProjectMatrix | Mat4 | 输出 | 投影矩阵 |
| gl_ModelViewProjectMatrix | Mat4 | 输出 | 模型视图投影变换矩阵 |
| gl_NormalMatrix | Mat4 | 输出 | 法向量变换到视空间矩阵 |
| gl_TextureMatrix[gl_MatTextureCoords] | Mat4 | 输出 | 各纹理变换矩阵 |
片元着色器
| 类型 | 说明 | 描述 | |
|---|---|---|---|
| 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 | 输出 | 使用gl_DrawBuffers输出的数据数组,不能和gl_FragColor结合使用 |
| gl_FragColor | vec4 | 输出 | 输出的颜色用于随后的像素操作 |
| gl_FragDepth | float | 输出 | 输出的深度用于随后的像素操作,未写时会使用固定功能管线的深度值替代 |
操作符:
| 操作符 | 描述 |
|---|---|
| () | 用于表达式组合,函数调用构造 |
| [] | 数组下标,向量或矩阵的选择器 |
| . | 结构体和向量的成员选择 |
| ++ -- | 前缀或后缀的自增、自减操作符 |
| + - ! | 一元操作符,表示正、负、逻辑非 |
| * / | 乘、除操作符 |
| + - | 二元操作符,表示加、减操作 |
| "<" ">" "<=" ">=" "==" "!=" | 小于、大于、小于或等于、大于或等于、等于、不等于判断符 |
| "&&" "||" "^^" | 逻辑与、或、异或 |
| ?: | 条件判断符 |
| = += -= *= /= | 赋值操作符 |
| , | 表示系列 |