GLSL支持下面几种基本类型。
类型 | 解释 |
---|---|
void | void,函数不需要返回值时用这个 |
bool | 布尔类型,true或者false |
int | 有符号整数 |
float | 有符号浮点数 |
vec2 | 包含2个float的向量 |
vec3 | 包含3个float的向量 |
vec4 | 包含4个float的向量 |
bvec2 | 包含2个bool的向量 |
bvec3 | 包含3个bool的向量 |
bvec4 | 包含4个bool的向量 |
ivec2 | 包含2个int的向量 |
ivec3 | 包含3个int的向量 |
ivec4 | 包含4个int的向量 |
mat2 | 2*2的float的矩阵 |
mat3 | 3*3的float的矩阵 |
mat4 | 4*4的float的矩阵 |
sampler2D | 操作2D的Texture的句柄 |
samplerCube | 操作cube的Texture的句柄 |
另外,GLSL不支持指针类型。
GLSL支持结构体,把一些系统定义的类型聚到一起,组成自定义的类型。例如:
struct light {
float intensity;
vec3 position;
} lightVar;
然后,可以通过下面的方式声明一个结构体:
light lightVar2;
和C++中的结构体差不多。结构体里最少有一个成员,而且不支持结构体的嵌套。
GLSL中的数组和C++的数组很类似,支持最基本类型,也支持结构体。例如:
float frequencies[3];
uniform vec4 lightPosition[4];
const int numLights = 2;
light lights[numLights];
GLSL的数组无法在声明的时候初始化。
限定符 | 含义 |
---|---|
本地可读可写,或者是函数的参数 | |
const | 常量,或者是函数的只读参数 |
attribute | 连接Vertex Shader和OpenGL ES |
uniform | 不会改变的常量 |
varying | 连接Vertex Shader和Fragment Shader,提供差值 |
成员变量、局部变量以及函数参数只能使用const。 函数返回值和结构体内的变量不适用限定符。 成员变量没有标明限定符,或者标了const的,必须在声明的时候初始化。uniform、attribute、varying这三个不受此限制。
const限定符标识一个只读常量,在声明的时候就必须初始化。例如:
const vec3 zAxis = vec3 (0.0, 0.0, 1.0);
但是,结构体里的变量不能设成const,数组以及包含数组的结构体也不能设成const,因为数组无法在声明的时候初始化。
attribute是用来给Vertex Shader传递顶点数据的,只能用在Vertex Shader中。一般通过OpenGL API来初始化。
attribute 无法修饰数组和结构体。
具体:
attribute vec4 position;
attribute vec3 normal;
attribute vec2 texCoord;
uniform是只读的,只能通过OpenGL API进行初始化。举例:
uniform vec4 lightPosition;
Varying变量是连接Vertex Shader和Fragment Shader的桥梁,Vertex Shader会为每个Vertex计算颜色、坐标等信息,写入Varying变量。然后Fragment Shader会读取这些数据进行进一步的操作。
这里比较难理解的就是差值,还是要通过实例来理解。举个例子,比如一张图片要绘制一千个Fragment(可以理解成需要绘制一千个像素点),我们不可能挨个去赋值,只能通过系统自动差值的方式实现。
Vertex Shader可以写Varying变量,也可以读,Fragment Shader只能读Varying变量,不能写。Vertex Shader中定义的Varying变量必须和Fragment Shader中的定义完全匹配。不能多定义Varying变量,也不能少定义。Fragment Shader中定义的Varying变量必须在Vertex Shader中有完全一样的定义。
关于Vertex Shader和Fragment Shader中Varying变量的定义关系,有个图:
上图中的static use是指在Shader中有明确的使用,比如读写等操作。
Varying变量声明举例:
varying vec3 normal;
Varying变量不可应用于结构体。
函数的参数可以使用下面的三个参数限定符。
限定符 | 作用 |
---|---|
< none: default > | 和 in 完全一样 |
in | 传给函数,在函数中读取值 |
out | 传给函数,在函数中写入值;传给函数的时候没有初始化 |
inout | in 和 out 作用的结合 |