如何使用几何体着色器创建的坐标绘制TRIANGLE_FAN?(GLSL 3.3)



我想用一个GS画多个粉丝。每个粉丝每次都应该对着相机做广告,这使得每个顶点都必须乘以MVP矩阵。由于每个风扇都可以由用户移动,我想出了给GS提供位置的想法。

以下几何体着色器按预期工作,点为输入和输出:

uniform mat4 VP;
uniform mat4 sharedModelMatrix;
const int STATE_VERTEX_NUMBER = 38;
layout (shared) uniform stateShapeData {
    vec2 data[STATE_VERTEX_NUMBER];
};
layout (triangles) in;
layout (triangle_strip, max_vertices = 80) out;
void main(void)
{
    int i;
    mat4 modelMatrix = sharedModelMatrix;
    modelMatrix[3]   = gl_in[0].gl_Position;
    mat4 MVP = VP * modelMatrix;
    gl_Position = MVP * vec4( 0, 0 , 0, 1 );
    EmitVertex(); // epicenter
    for (i = 37; i >= 0; i--) {
        gl_Position = MVP * vec4( data[i], 0, 1 );
        EmitVertex();
     }
     gl_Position = MVP * vec4( data[0], 0, 1 );
     EmitVertex();
}

我试着用glDrawElementsglDrawArraysglMultiDrawArrays运行这个。这些命令都不会绘制完整的扇形图。每个绘制第一个填充的三角形和其余顶点作为点。

所以,最根本的问题是:有可能用GS创建的顶点绘制一个扇形吗?如何绘制?

正如您所发现的,在几何着色器中输出风扇是非常不自然的。

您当前正在按扇形顺序输出顶点,这是一个在基本体装配后与GPU完全无关的构造。风扇作为汇编程序的输入很有用,但就输出而言,光栅化器只了解条的概念。

若要正确编写此着色器,需要将此扇形分解为一系列单独的三角形。这意味着您编写的循环实际上将在每次迭代中输出中心。

void main(void)
{
    int i;
    mat4 modelMatrix = sharedModelMatrix;
    modelMatrix[3]   = gl_in[0].gl_Position;
    mat4 MVP = VP * modelMatrix;
    for (i = 37; i >= 0; i--) {
        gl_Position = MVP * vec4( 0, 0 , 0, 1 );
        EmitVertex(); // epicenter
        gl_Position = MVP * vec4( data[i], 0, 1 );
        EmitVertex();
        gl_Position = MVP * vec4( data[i-1], 0, 1 );
        EmitVertex();
        // Fan and strip DNA just won't splice
        EndPrimitive ();
     }
}

以这种方式绘制时,不能利用条形图排序;您最终不得不多次结束输出原语(strip)。按扇形顺序绘制的唯一可能的好处是在循环中缓存位置。如果您知道几何体着色器应该输出三角形条带,为什么不从一开始就对输入顶点进行排序呢?

最新更新