1

我想显示一个简单的 UV 球体(从 Blender 导出)并使用独特的几何着色器生成具有法线坐标的线条。

第一次,我编写了一个简单的几何着色器,它简单地将输入顶点信息返回到片段着色器。为了简单起见(例如),我删除了片段着色器中的亮度计算。

顶点着色器:

#version 400

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;

uniform mat4 MVP;

out vec3 VPosition;
out vec3 VNormal;

void main(void)
{
    VNormal = VertexNormal;
    gl_Position = vec4(VertexPosition, 1.0f);   
}

几何着色器:

#version 400

layout(points) in;
layout(line_strip, max_vertices = 2) out;

uniform mat4 MVP;

in vec3 VNormal[];

out vec3 fcolor;

void main(void)
{
    float size = 2.5f;

    fcolor = vec3(0.0f, 0.0f, 1.0f);
    gl_Position = MVP * gl_in[0].gl_Position;
    EmitVertex();

    fcolor = vec3(1.0f, 1.0f, 0.0f);
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xyz + vec3(
        VNormal[0].x * size, VNormal[0].y * size, VNormal[0].z * size), 1.0f);
    EmitVertex();

    EndPrimitive();
}

和片段着色器:

#version 400

in vec3 Position;
in vec3 Normal;
in vec2 TexCoords;

out vec4 FragColor;

in vec3 fcolor;

void main(void)
{
    FragColor = vec4(fcolor, 1.0f);
}

现在在 C++ 代码中要绘制的原始类型(这里是三角形):

glDrawArrays(GL_TRIANGLES, 0, meshList[idx]->getVertexBuffer()->getBufferSize());

最后是输出:

在此处输入图像描述

直到这里一切都好。现在我想在球体上生成股线作为法线。为了完成这项工作,我编写了以下几何着色器(顶点和片段着色器是相同的)。

#version 400

layout(points) in;
layout(line_strip, max_vertices = 2) out;

uniform mat4 MVP;

in vec3 VNormal[];

out vec3 fcolor;

void main(void)
{
    float size = 1.0f;

    fcolor = vec3(0.0f, 0.0f, 1.0f);
    gl_Position = MVP * gl_in[0].gl_Position;
    EmitVertex();

    fcolor = vec3(1.0f, 1.0f, 0.0f);
    gl_Position = MVP * vec4(gl_in[0].gl_Position.xyz + vec3(
        VNormal[0].x * size, VNormal[0].y * size, VNormal[0].z * size), 1.0f);
    EmitVertex();

    EndPrimitive();
}

输入原始类型是点我修改了 C++ 代码来绘制场景:

glDrawArrays(GL_POINTS, 0, meshList[idx]->getVertexBuffer()->getBufferSize());

和输出:

在此处输入图像描述

最后,如果我想在几何着色器中将三角形输入作为输入图元,将 line_strip 作为输出图元,我有以下着色器:

#version 400

layout(triangles, invocations = 3) in;
layout(line_strip, max_vertices = 6) out;

uniform mat4 MVP;

in vec3 VNormal[];

out vec3 fcolor;

void main(void)
{
    float size = 1.0f;

    for (int i = 0; i < 3; i++)
    {
        fcolor = vec3(0.0f, 0.0f, 1.0f);
        gl_Position = MVP * gl_in[i].gl_Position;
        EmitVertex();

        fcolor = vec3(1.0f, 1.0f, 0.0f);
        gl_Position = MVP * vec4(gl_in[0].gl_Position.xyz + vec3(
        VNormal[0].x * size, VNormal[0].y * size, VNormal[0].z * size), 1.0f);
        EmitVertex();

            EndPrimitive();
    }
}

输出如下:

在此处输入图像描述

但我的目标是使用相同的几何着色器在一个输出中显示场景(球体+股线)。我想知道是否可以这样做。我不这么认为,因为几何着色器必须只有一种类型的输入基元和另一种输出类型,而不是几种类型。我想确定它是否可能。

4

1 回答 1

0

谁知道,也许有一天会有一个扩展,可以从几何着色器发出多种原始类型,但正如你所说,目前还不能做到。

一种替代方法可能是用三角形绘制法线。

另一个,但在这种情况下完全没用,可能是使用变换反馈扩展来保存顶点着色器结果,并使用两个单独的几何着色器重用该数据。我只提到这一点是因为它是我能想到的在顶点阶段之后发出多种原始类型最接近的事情。

编辑
用于绘制法线的两个几何着色器让我感到困惑。在第二个中max_vertices = 3,应该是63 条单独的线,EndPrimitive也应该在 for 循环内,因此 3 条线没有连接。但是您已经通过GL_POINTS在上一个中绘制来解决这个问题。如果支持,这是否旨在为多个原始输出构建?(固定的)

鉴于您的几何图形重用了许多顶点,索引 withglDrawElements会更有效。尽管您仍然希望glDrawArrays用于绘制法线以避免绘制索引数组引用的重复顶点。

于 2013-11-05T15:40:03.610 回答