Geometry Shader
in/out layout qualifier
几何着色器需要定义输入的图元以及输出的图元信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #version 460 core layout (points) in; layout (line_strip, max_vertices = 2) out;
void main() { gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0); EmitVertex();
gl_Position = gl_in[0].gl_Position + vec4( 0.1, 0.0, 0.0, 0.0); EmitVertex(); EndPrimitive(); }
|
输入的图元可以使用以下任意一种类型:
- points: when drawing GL_POINTS primitives (1).
- lines: when drawing GL_LINES or GL_LINE_STRIP (2).
- lines_adjacency: GL_LINES_ADJACENCY or GL_LINE_STRIP_ADJACENCY (4).
- triangles: GL_TRIANGLES, GL_TRIANGLE_STRIP or GL_TRIANGLE_FAN (3).
- triangles_adjacency : GL_TRIANGLES_ADJACENCY or GL_TRIANGLE_STRIP_ADJACENCY (6).
输出的图元仅可以使用以下三种类型:
- points
- line_strip
- triangle_strip
几何着色器允许在渲染管线中动态的生成几何体。即使绘制命令只指定了最基础的图元(比如4个点),几何着色器也能将这些点实时扩展为更复杂的形状,从而用非常简单的输入创造出丰富的视觉效果。
glDrawArrays/glDrawElements中传入的图元类型对应了几何着色器中输入的图元类型(in)
Varyings
顶点着色器定义的输出变量,几何着色器需要用数组来接收
Examples
Explode
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 32 33 34 35 36 37 38 39 40 41 42
| #version 460 core layout (triangles) in; layout (triangle_strip, max_vertices = 3) out;
in VS_OUT { vec2 texCoords; } gs_in[];
out vec2 TexCoords;
uniform float time;
vec4 explode(vec4 position, vec3 normal) { float magnitude = 2.0; vec3 direction = normal * ((sin(time) + 1.0) / 2.0) * magnitude; return position + vec4(direction, 0.0); }
vec3 GetNormal() { vec3 a = vec3(gl_in[0].gl_Position) - vec3(gl_in[1].gl_Position); vec3 b = vec3(gl_in[2].gl_Position) - vec3(gl_in[1].gl_Position); return normalize(cross(a, b)); }
void main() { vec3 normal = GetNormal();
gl_Position = explode(gl_in[0].gl_Position, normal); TexCoords = gs_in[0].texCoords; EmitVertex(); gl_Position = explode(gl_in[1].gl_Position, normal); TexCoords = gs_in[1].texCoords; EmitVertex(); gl_Position = explode(gl_in[2].gl_Position, normal); TexCoords = gs_in[2].texCoords; EmitVertex(); EndPrimitive(); }
|
Visualizing normal vectors
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #version 460 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aNormal;
out VS_OUT { vec3 normal; } vs_out;
uniform mat4 view; uniform mat4 model;
void main() { gl_Position = view * model * vec4(aPos, 1.0); mat3 normalMatrix = mat3(transpose(inverse(view * model))); vs_out.normal = normalize(vec3(vec4(normalMatrix * aNormal, 0.0))); }
|
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
| #version 460 core layout (triangles) in; layout (line_strip, max_vertices = 6) out;
in VS_OUT { vec3 normal; } gs_in[];
const float MAGNITUDE = 0.4; uniform mat4 projection;
void GenerateLine(int index) { gl_Position = projection * gl_in[index].gl_Position; EmitVertex(); gl_Position = projection * (gl_in[index].gl_Position + vec4(gs_in[index].normal, 0.0) * MAGNITUDE); EmitVertex(); EndPrimitive(); }
void main() { GenerateLine(0); GenerateLine(1); GenerateLine(2); }
|