最简单的几何着色器(Geometry Shader)【OpenGL】【GLSL】
发表于2018-02-07
下面给大家接一个最简单的几何着色器,以绘制模型的法线的为例,效果如图:
Torus:
Dragon:
关键代码如下:
1.顶点着色器
static const char * vs_source[] = { "#version 410 core \n" " \n" "layout (location = 0) in vec4 position; \n" "layout (location = 1) in vec3 normal; \n" " \n" "out VS_OUT \n" "{ \n" " vec3 normal; \n" " vec4 color; \n" "} vs_out; \n" " \n" "void main(void) \n" "{ \n" " gl_Position = position; \n" " vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0); \n" " vs_out.normal = normalize(normal); \n" "} \n" };
2.几何着色器
static const char * gs_source[] = "#version 410 core \n" " \n" "layout (triangles) in; \n" // 输入的图元类型 "layout (line_strip, max_vertices = 7) out; \n" // 输出的图元类型和最大的顶点数 " \n" "uniform mat4 mv_matrix; \n" "uniform mat4 proj_matrix; \n" " \n" "in VS_OUT \n" // 顶点着色器输出的顶点属性 "{ \n" " vec3 normal; \n" " vec4 color; \n" "} gs_in[]; \n" " \n" "out GS_OUT \n" // 几何着色器输出的顶点属性 "{ \n" " vec3 normal; \n" " vec4 color; \n" "} gs_out; \n" " \n" "uniform float normal_length = 0.4; \n" " \n" "void main(void) \n" "{ \n" " mat4 mvp = proj_matrix * mv_matrix; \n" " vec3 ab = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz; \n" " vec3 ac = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz; \n" " vec3 face_normal = normalize(cross(ab, ac)); \n" " \n" " vec4 tri_centroid = (gl_in[0].gl_Position + \n" " gl_in[1].gl_Position + \n" " gl_in[2].gl_Position) / 3.0; \n" " \n" " gl_Position = mvp * tri_centroid; \n" " gs_out.normal = gs_in[0].normal; \n" " gs_out.color = gs_in[0].color; \n" " EmitVertex(); \n" // 生成新顶点 " \n" " gl_Position = mvp * (tri_centroid + \n" // 三角图元的中心法线 " vec4(face_normal * normal_length, 0.0)); \n" " gs_out.normal = gs_in[0].normal; \n" " gs_out.color = gs_in[0].color; \n" " EmitVertex(); \n" " EndPrimitive(); \n" // 结束本图元(以下为新图元) " \n" //" gl_Position = mvp * gl_in[0].gl_Position; \n" // 第一个顶点的法线 //" gs_out.normal = gs_in[0].normal; \n" //" gs_out.color = gs_in[0].color; \n" //" EmitVertex(); \n" //" \n" //" gl_Position = mvp * (gl_in[0].gl_Position + \n" //" vec4(gs_in[0].normal * normal_length, 0.0)); \n" //" gs_out.normal = gs_in[0].normal; \n" //" gs_out.color = gs_in[0].color; \n" //" EmitVertex(); \n" //" EndPrimitive(); \n" " \n" " gl_Position = mvp * gl_in[0].gl_Position; \n" // 三角形的三个顶点 " gs_out.normal = gs_in[0].normal; \n" " gs_out.color = vec4(1.); \n" " EmitVertex(); \n" " \n" " gl_Position = mvp * gl_in[1].gl_Position; \n" " gs_out.normal = gs_in[1].normal; \n" " gs_out.color = vec4(1.); \n" " EmitVertex(); \n" " \n" " gl_Position = mvp * gl_in[2].gl_Position; \n" " gs_out.normal = gs_in[2].normal; \n" " gs_out.color = vec4(1.); \n" " EmitVertex(); \n" " EndPrimitive(); \n" "} \n" ;
3.片元着色器
static const char * fs_source[] = { "#version 410 core \n" " \n" "out vec4 color; \n" " \n" "in GS_OUT \n" "{ \n" " vec3 normal; \n" " vec4 color; \n" "} fs_in; \n" " \n" "void main(void) \n" "{ \n" " color = fs_in.color * abs(normalize(fs_in.normal).z); \n" "} \n" };