变量
void
表示空,用于无返回值的函数。比如顶点shader中main函数:
void main() {
gl_Position = vPosition;
}
float、int、bool
分别代表浮点型,整型,布尔型。定义各类型变量如下:
float f = 1.0;
int i =0;
bool b = true;
vec2、vec3、vec4
分别包含2、3、4个float类型的向量。定义变量如下:
vec2 v2 = vec2(1.0, 0.0);
vec3 v3 = vec3(1.0, 0.0, 0.5);
vec4 v4 = vec4(1.0, 0.0, 0.5,0.5);
如果只给一个参数,则向量中其他值也会使用此值,比如给vec4一个1.0的值:
vec4 v5 = vec4(1.0);
等价于:
vec4 v5 = vec4(1.0,1.0,1.0,1.0);
注意提供给向量的参数只能是1个或者对应向量个数,比如vec4类型不能提供2个参数:
vec4 v6 = vec4(1.0,1.0);
上面给vec4提供2个参数的写法是错误的。
经常使用的内置变量gl_Position和gl_FragColor就是vec4类型,在片段shader中设置颜色:
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
ivec2, ivec3, ivec4和vec2、vec3、vec4用法一样,区别就是ivec的参数是int类型。
bvec2, bvec3, bvec4和vec2、vec3、vec4用法一样,区别就是bvec的参数是bool类型。
向量分量
获取向量分量有2种方式:
- 通过 “.” 符号获取,向量分量为{x, y, z, w} , {r, g, b, a} 或 {s, t, r, q} 。{x, y, z, w}是位置相关的分量,{r, g, b, a}是颜色相关的分量,{s, t, r, q}是纹理坐标相关的分量,但是(x,y,z,w)、(r,g,b,a)和(s,t,r,q)不能混合使用。
- 通过数组下标获取,例如v2[0]。
用法如下:
vec4 v4 = vec4(1.0, 0.0, 0.5,0.5);
float a = v4.x;
vec2 v2 = v4.xy;
vec4 v5 = vec4(v4.x,v4.y,v4.z,v4.w);
vec4 color = vec4(v4.r,v4.g,v4.b,v4.a);
mat2, mat3, mat4
分别表示2x2,3x3,4x4浮点型矩阵。如果只提供一个参数,则该值做为矩阵对角线的值,也就是单位矩阵,比如mat4(1.0),就是4x4单位矩阵。
也可以按照如下方式定义矩阵:
mat3 m3 = mat3(1.0, 0.0, 0.0, // 第一列
0.0, 1.0, 0.0, // 第二列
0.0, 1.0, 1.0); // 第三列
sampler2D、samplerCube、samplerExternalOES
- sampler2D:2D纹理,可以用于绘制图片。
- samplerCube:立方体纹理。
- samplerExternalOES:Android端用于绘制视频或者相机预览,使用samplerExternalOES需要在shader头部添加 #extension GL_OES_EGL_image_external : require,用法如下:
#extension GL_OES_EGL_image_external : require
uniform samplerExternalOES u_Texture;
结构体
在GLSL中允许声明结构体,和c语言类型,声明如下:
struct myStruct
{
vec4 color;
vec4 position;
} myVertex;
声明了一个myStruct类型的变量myVertex。初始化如下:
myVertex = myStruct(vec4(0.0, 1.0, 0.0, 0.0),vec4(0.5, 0.5,0.5, 0.5));
类型要和结构体中一一对应。
获取结构体值的方式如下:
vec4 color = myVertex.color;
vec4 position = myVertex.position;
基本语句
if-else
if-else 是条件判断语句,用法如下:
if (color.a < 0.25) {
gl_FragColor = vec4(1,0,0,1);
} else {
gl_FragColor = vec4(1,0,0,color.a);
}
for 循环
使用for循环时,循环变量必须是编译时已知,用法如下:
float sum = 0;
for (int i = 0; i < 10; i++) {
sum += i;
}
第一种典型的错误用法:
float myArr[4];
float sum = 0;
for (int i = 0; i < 3; i++) {
sum += myArr[i];
}
[ ]中只能为常量或 uniform 变量,不能为整数量变量(如:i,j,k)。
第二种典型的错误用法:
uniform int loopIter;
for (int i = 0; i < loopIter; i++) {
sum += i;
}
上面的用法是错误的,循环变量 loopIter 的值必须是编译时已知。
函数
函数的用法和C语言基本相同,在GLSL中不能递归调用且必须声明返回值类型,如果没有返回值则使用void。用法如下:
vec4 getPosition(float a){
return vec4(0.0,0.0,0.0,a);
}
void main(){
}
精度限定符
在GLSL中精度限定符分为低(lowp)、中(mediump)、高(highp)精度。当使用低精度时可以更加高效的运行,当然如果精度不合理可能会出现失真的问题,曾经在项目中遇到过拍照黑边的问题就是精度的问题引起的。
指定默认精度方式如下:
precision mediump float;
如果未使用的精度限定符的变量将会使用此默认值,用法如下:
//指定精度
highp vec4 position;
//默认精度
vec4 color;
更多相关阅读:
转载:https://blog.csdn.net/mengks1987/article/details/104104990