更新于 

程序流程控制

分支与循环

if和if-else语句
1
2
3
4
5
6
float distance = 0.7;
if(distance<0.5){
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}else{
gl_FragColor = vec4(0.0,1.0,0.0,1.0);
}
TIP1:

判断式中不可以使用布尔值类型矢量

TIP2:

GLSL ES中没有 switch语句

for语句
1
2
3
4
int sum = 0;
for(int i = 0;i<3;i++){
sum += i;
}
continue、break、discard语句

continue

1
2
3
4
5
for(int i = 0; i<10; i++){
if(i==8){
continue; // 跳过循环体,开启下一段循环
}
}

break

1
2
3
4
5
6
	for(int i = 0;i<10;i++){
if(i == 8){
break;
}
}
}
discard

只能在Fragment shader中使用,表示放弃当前片元直接处理下一个片元。

函数

函数声明
1
2
3
4
返回类型函数名 (type0 arg0, type1 arg1, ..., typen argn){
执行语句
return 返回值;
}

如果没有return语句,一定要声明函数是void类型

注意:

GLSL ES不允许递归调用,这是为了便于编译器对函数进行内联展开。

小例子:将RGBA颜色值转化为亮度值的函数

1
2
3
4
5
6
7
8
9
10
11
float luma(vec4 color){ //函数声明
return
0.2126 * color.r +
0.7162 * color.g +
0.0722 * color.b;
}

attribute vec4 a_Color;
void main(){
float brightness = luma(a_Color); //函数调用
}
规范声明

如果在函数声明之前就进行调用,
必须在调用之前进行 规范声明

规范声明的目的在于:

告诉WebGL系统函数的参数参数类型返回值等等。

1
2
3
4
5
6
7
8
9
10
11
12
float luma(vec4); //规范声明

void main(){
vec4 a_Color = vec4(0.5,0.0,0.0,1.0);
float brightness = luma(a_Color);
}
float luma(vec4 color){
return
0.2126 * color.r +
0.7162 * color.g +
0.0722 * color.b;
}
参数限定词

参数限定词可以用来控制参数的行为,大体上包括:

  • 传入函数的
  • 要被赋值并传出函数的
  • 要被传入、赋值、传出函数的

in是默认的参数限定字。

使用参数限定词重写luma函数

1
2
3
4
5
6
7
8
9
void luma(in vec3 color, out float brightness){
brightness = 0.2126 * color.r + 0.7162 * color.g + 0.0722 * color.b;
}

void main(){
vec3 v3 = vec3(0.0,1.0,1.0);
float brightness;
luma(v3, brightness);
}
内置函数