几何着色器
概述
几何着色器(Geometry Shader)是pipeline中的可选阶段,位于vertex shader和tcs和tes之后,在fragment shader之前,几何着色器用单个基元作为输入,然后输入零个或多个基元,所以理论上geometry shader阶段可以更改图元类型
示例
vertex shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 in_color;
layout(location = 2) in float in_point_size;
layout(location = 0) out vec4 vout_color;
layout(location = 1) out float vout_point_size;
void main()
{
gl_Position = vec4(position, 1.0);
gl_PointSize = in_point_size;
vout_color = vec4(in_color, 1.0);
vout_point_size = in_point_size;
}geometry shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
struct Vertex {
vec4 color;
float point_size;
};
layout(triangles, invocations =1) in;
layout(location = 0) in Vertex vout[];
layout(points, max_vertices = 4) out;
layout(location = 0) out Vertex gout;
void generate(int i) {
gl_Position = (gl_in[i].gl_Position + gl_in[(i+1)%3].gl_Position) / 2;
gl_PointSize = vout[i].point_size;
gout.color = vout[i].color;
gout.point_size = vout[i].point_size;
EmitVertex();
}
void main() {
generate(0);
generate(1);
generate(2);
gl_Position = (gl_in[0].gl_Position + gl_in[1].gl_Position + gl_in[2].gl_Position) / 3;
gl_PointSize = (vout[0].point_size + vout[1].point_size + vout[2].point_size) / 3;
gout.color = (vout[0].color + vout[1].color + vout[2].color) / 3;
gout.point_size = gl_PointSize;
EmitVertex();
}fragment shader
1
2
3
4
5
6
7
8
layout(location = 0) in vec4 vout_color;
layout(location = 1) in float vout_point_size;
layout(location = 0) out vec4 fout_color;
void main() {
fout_color = vout_color;
}
输出图片如上图所示,和例子相符,输入的顶点数据格式为1
2
3
4
5
6// x y z r g b point_size
// 每个顶点为坐标xyz,然后是rgb,最后是点的大小
// 每个顶点数据用7个float表示
// 0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 3.0, // 0
// 0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 9.0, // 2
// -0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 15.0, // 2
关键字说明
layout(triangles, invocations =1) in
:这条语句表示基本输入的图元是三角形 invocations=1定义了几何着色器的实例化次数为1,表示每个输入的图元会被处理invocation次,这个值不设置默认为1layout(points, max_vertices = 4) out;
:这条语句表示gs输出的图元为点类型,而max_vertices表示最多生成4个新的顶点
1 | void generate(int i) { |
这个函数的功能是取三角形的两个顶点的中点,在中点的位置生成新的点EmitVertex()
:表示将生成的点发送到pipeline的下一个阶段(fragment shader)