GLSL语法与C语言类似。
1、变量类型
基础类型:bool,int,uint,float,double与C语言的类型类似。
向量类型:vecN,bvecN,ivecN,uvecN,dvecN,N表示向量维数(N=1,2,3,4),含前缀b为bool向量,i为int向量,u为uint向量,d为double向量,不含前缀为float向量,可以通过.xyzw(直角坐标)或者.rgba(颜色分量)或者.stpq(纹理坐标)分别访问第1、2、3、4个分量,并且分量可以随其重组,构成新的向量。向量用法示例:
vec2 v2 = vec2(0.0,1.0);
vec3 v3 = v2.xxy; //v3=(0.0,0.0,1.0)
vec4 v4 = vec4(v3.zyx,0.1); //v4=(1.0,0.0,0.0,0.1)
vec4 v41 = vec4(v2,0.1,0.2); //v41=(0.0,1.0,0.1,0.2)
矩阵类型:mat2,mat3,mat4分别为2x2,3x3,4x4 float矩阵,如mat2 m=mat2(1.0,2.0,3.0,4.0);构造一个2x2的矩阵,(1.0,2.0)为第一列,(3.0,4.0)为第二列。
纹理类型:sampler2D,samplerCube分别为2D纹理和立方体纹理;
结构体:与C语言结构体类似;
数组:与C语言数组类似,但GLSL中只能使用一维数组。
2、变量限定符
in和out:in和out设定变量为输入或输出,out标识的变量被送往下一着色器阶段,如果在下一阶段的in变量与该out变量相同(名称和类型都要相同),则使用该out变量的值。in和out还可以用于接口块(Interface Block),以传送一组数据,如下面示例的Interface_Block。如果片段着色器定义out vec4变量,则该变量就是最终的像素颜色。此外为方便在OpenGL中找到变量位置,可使用layout,layout(location=n)标识变量的位置,OpenGL中glVertexAttribPointer的第一个参数就是这个n的值,通过这个位置可以很方便设置顶点属性,如果没有这个标识符,则需要在OpenGL中使用glGetAttribLocation查找变量位置。
//顶点着色器
#version 330 core
layout (location = 0) in vec3 vertexPos;
out vec4 vertexColor;
out Interface_Block
{
vec4 vColor;
} ib_out;
void main()
{
gl_Position = vec4(vertexPos, 1.0);
vertexColor = vec4(1.0, 0.0, 0.0, 1.0);
ib_out.vColor= vec4(0.0, 1.0, 0.0, 1.0);
}
//片段着色器
#version 330 core
out vec4 FragColor;//最终的颜色
in vec4 vertexColor; // 使用顶点着色器中的vertexColor
in Interface_Block//接口块块名须保持一致,实例名可以不一样
{
vec4 vColor;
} ib_in;
void main()
{
FragColor = vertexColor;
//FragColor = ib_in.vColor;//使用顶点着色器中ib_out.vColor
}
uniform:uniform标识的变量为全局变量,可以被任意着色器在任意阶段访问,可以在OpenGL程序中以glGetUniformLocation函数获取变量位置,以glUniform前缀的函数随时修改其值。
#version 330 core
uniform vec4 uniformColor; // 使用glUniform4f函数改变这个变量值
out vec4 FragColor;
void main()
{
FragColor = uniformColor;
}
3、流控制
流控制与C语言类似,有if else,switch case,for,while,do while。
4、函数
函数的定义与C语言类似,着色器的执行入口也是main()函数。
5、内建变量
gl_Position | 可写,顶点着色器裁剪空间输出位置 |
gl_PointSize | 可写,绘制GL_POINTS时的点大小 |
gl_VertexID | 只读,正在绘制顶点的ID,一般是顶点的索引 |
gl_FragCoord | 只读,片段在窗口空间坐标,原点在左下角,x,y值介于glViewport设置的视口大小之间,z值为深度值 |
gl_FrontFacing | 只读,用于判断片段是属于正面还是反面 |
gl_FragDepth | 可写,可设置片段的深度值 |
6、内建函数
(1)基本函数
abs(x) | x的绝对值 |
sign(x) | 返回x的符号,用-1,0,1表示 |
floor(x) | 小于或等于x的最接近整数 |
ceil(x) | 大于或等于x的最接近整数 |
fract(x) | x的小数部分 |
mod(x,y) | x/y的余 |
min(x,y) max(x,y) | 最小最大值 |
clamp(x,minVar,maxVar) | 将x限制在minVar和maxVar之间 |
mix(x,y,a) | x*(1-a)+y*a |
step(edge,x) | x |
smoothstep(edge0,edge1,x) | x<=edge0时返回0,x>=edge1返回1,否则返回介于0和1之间的值 |
(2)三角函数
radians(x) | 角度转弧度 |
degrees(x) | 弧度转角度 |
sin cos tan asin acos atan | 三角函数 |
(3)指数函数
pow(x,y) exp(x) exp2(x) | x的y次方,e的x次方,2的x次方 |
log(x) log2(x) | e为底的对数,2为底的对数 |
sqrt(x) inversesqrt(x) | 平方根和平方根的倒数 |
(4)几何函数
length(x) | 向量x的长度 |
distance(x,y) | 向量x到向量y的距离 |
dot(x,y) cross(x,y) | 向量x和向量y的点积,叉积 |
normalize(x) | 向量x标准化 |
reflect (x, N) |
向量x在法向量为N的面上的反射向量x–2∗dot(N, x)∗N |
faceforward(N, x,y) | xy面朝向,dot(x,y)<0则返回N,否则返回-N |
refract(x,N,eta) | 向量x在法向量为N,折射率为eta的平面上的折射向量 |
(5)纹理函数
texture(sampler,coord) | 如果是2D纹理采样,sampler为采样的纹理,coord为vec2类型的坐标 如果是立方体纹理采样,sampler为采样的立方体纹理,coord为vec3类型的坐标 |