OpenGL 几何着色器的应用
关于几何着色器
从 OpenGL 3.2 开始,在顶点着色器和片段着色器之间有第三种可选类型的着色器,称为几何着色器。该着色器具有使用顶点着色器的输出作为输入动态创建新几何体的独特能力。
几何着色器在渲染管道中的位置:

应用1:几何着色器生成Bézier曲线
Bézier曲线方程:

需要4个控制点:

beziercurve.geom
#version 330 core
layout( lines_adjacency ) in;
layout( line_strip, max_vertices = 200 ) out;
void main() {
int uNum = 3;
float dt = 1. / float(uNum);
float t = 0.;
for( int i = 0; i <= uNum; i++ )
{
float omt = 1. - t;
float omt2 = omt * omt;
float omt3 = omt * omt2;
float t2 = t * t;
float t3 = t * t2;
gl_Position = omt3 * gl_in[0].gl_Position.xyzw
+ 3. * t * omt2 * gl_in[1].gl_Position.xyzw
+ 3. * t2 * omt * gl_in[2].gl_Position.xyzw
+ t3 * gl_in[3].gl_Position.xyzw;
fColor = vec3(1.0, 1.0, 1.0);
EmitVertex();
t += dt;
}
EndPrimitive();
}
应用二:几何着色器生成爆破物体
当我们说爆破一个物体时,我们并不是指要将宝贵的顶点集给炸掉,我们是要将每个三角形沿着法向量的方向移动一小段时间。效果就是,整个物体看起来像是沿着每个三角形的法线向量爆炸一样。
geom.gs
#version 330 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();
}

应用三:法向量可视化或生成毛发
Geom.gs
#version 330 core
layout (triangles) in;
layout (line_strip, max_vertices = 6) out;
in VS_OUT {
vec3 normal;
} gs_in[];
const float MAGNITUDE = 0.4;
void GenerateLine(int index)
{
gl_Position = gl_in[index].gl_Position;
EmitVertex();
gl_Position = gl_in[index].gl_Position + vec4(gs_in[index].normal, 0.0) * MAGNITUDE;
EmitVertex();
EndPrimitive();
}
void main()
{
GenerateLine(0); // 第一个顶点法线
GenerateLine(1); // 第二个顶点法线
GenerateLine(2); // 第三个顶点法线
}

Reference:
https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/09%20Geometry%20Shader/
https://web.engr.oregonstate.edu/~mjb/cs519/Handouts/geometry_shaders.1pp.pdf





One thought on “OpenGL 几何着色器的应用”
棒棒棒