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

How to draw TRIANGLE_FAN with geometry shader created coordinates? (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。 None 这些命令吸引了满满的粉丝。每个绘制第一个三角形填充和剩余的顶点作为点。

所以,最底层的问题是:是否可以使用 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 ();
     }
}

以这种方式绘制时不能利用条带顺序;您最终不得不多次结束输出基元(条带)。以扇形顺序绘制的唯一可能好处是循环内的缓存位置。如果您了解几何着色器应该输出三角形带,为什么不以这种方式开始对您的输入顶点进行排序?