计算机图形|OpenGL着色器语言GLSL语法总结

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) 弧度转角度
sincostanasinacosatan 三角函数





(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的平面上的折射向量

【计算机图形|OpenGL着色器语言GLSL语法总结】






(5)纹理函数
texture(sampler,coord) 如果是2D纹理采样,sampler为采样的纹理,coord为vec2类型的坐标
如果是立方体纹理采样,sampler为采样的立方体纹理,coord为vec3类型的坐标

    推荐阅读