在几何体着色器中传递带有布局的顶点属性

ttcibm8c  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(141)

假设我们有一个GL程序,该程序由以下顶点、几何体和碎片着色器组成。

顶点:


# version 410

layout (location = 0) in vec2 pos;
layout (location = 1) in vec2 size;
layout (location = 2) in float rot;
layout (location = 3) in vec4 color;

layout (location = 0) out vec2 p;
layout (location = 1) out vec2 s;
layout (location = 2) out float r;
layout (location = 3) out vec4 c;

void main(){
    gl_Position = vec4(pos,0.0,1.0);

    p = pos;
    s = size;
    r = rot;
    c = color;
}

几何体:


# version 410

layout (points) in;
layout (triangle_strip, max_vertices = 4) out;

layout (location = 0) in vec2 pos;
layout (location = 1) in vec2 size;
layout (location = 2) in float rot;
layout (location = 3) in vec4 color;

layout (location = 0) out vec2 p;
layout (location = 1) out vec2 s;
layout (location = 2) out float r;
layout (location = 3) out vec4 c;

void main()
{
    gl_Position = gl_in[0].gl_Position + vec4(-0.2, -0.2, 0.0, 0.0);    // 1:bottom-left
    EmitVertex();
    gl_Position = gl_in[0].gl_Position + vec4( 0.2, -0.2, 0.0, 0.0);    // 2:bottom-right
    EmitVertex();
    gl_Position = gl_in[0].gl_Position + vec4(-0.2,  0.2, 0.0, 0.0);    // 3:top-left
    EmitVertex();
    gl_Position = gl_in[0].gl_Position + vec4( 0.2,  0.2, 0.0, 0.0);    // 4:top-right
    EmitVertex();
    EndPrimitive();

    p = pos;
    s = size;
    r = rot;
    c = color;
}

片段:


# version 410

layout (location = 0) in vec2 pos;
layout (location = 1) in vec2 size;
layout (location = 2) in float rot;
layout (location = 3) in vec4 color;

out vec4 FragColor;

void main()
{
    FragColor = color;
}

该程序获取点数,并将它们显示为四边形。

我在这里尝试做的是通过几何体着色器将4个顶点属性(位置、大小、旋转和颜色)传递给碎片着色器。

如果我从我的程序中删除几何着色器,它会设法将顶点属性传递给片段着色器,并显示彩色的点。

如果我保留几何图形着色器并移除布局(输入和输出),它会显示黑色四边形。

我是不是漏掉了什么?

b4qexyjb

b4qexyjb1#

您的代码中有几个问题。我已经重命名了所有变量,这样您就可以看到发生了什么(这可能不会是一个大问题,因为您使用的是布局限定符,但我将坚持使用一个使发生的事情变得显而易见的命名)。


# version 410

// per-vertex attributes from the vertex buffers
layout (location = 0) in vec2 vs_pos;
layout (location = 1) in vec2 vs_size;
layout (location = 2) in float vs_rot;
layout (location = 3) in vec4 vs_color;

// per-vertex inputs to the geometry shader
layout (location = 0) out vec2 gs_pos;
layout (location = 1) out vec2 gs_size;
layout (location = 2) out float gs_rot;
layout (location = 3) out vec4 gs_color;

void main(){
    gl_Position = vec4(vs_pos,0.0,1.0);

    // pass vars from vertex shader, to geometry shader
    gs_pos = vs_pos;
    gs_size = vs_size;
    gs_rot = vs_rot;
    gs_color = vs_color;
}

# version 410

layout (points) in;
layout (triangle_strip, max_vertices = 4) out;

// when passed to the geometry shader, these variables are now arrays!
// be sure to declare them as such...
layout (location = 0) in vec2 gs_pos[];
layout (location = 1) in vec2 gs_size[];
layout (location = 2) in float gs_rot[];
layout (location = 3) in vec4 gs_color[];

// the outputs to the fragment shader are presented as
// single attributes though 
layout (location = 0) out vec2 fs_pos;
layout (location = 1) out vec2 fs_size;
layout (location = 2) out float fs_rot;
layout (location = 3) out vec4 fs_color;
void main()
{
    // pass vars for 1st vertex generated
    // (you may be able to get away with setting these once prior
    // to the first EmitVertex call, not sure, it's been a while!)
    fs_pos = gs_pos[0];
    fs_size = gs_size[0];
    fs_rot = gs_rot[0];
    fs_color = gs_color[0];    
    gl_Position = gl_in[0].gl_Position + vec4(-0.2, -0.2, 0.0, 0.0);
    EmitVertex(); //< emits all params above!

    // pass vars for 2nd vertex generated, etc... 
    fs_pos = gs_pos[0];
    fs_size = gs_size[0];
    fs_rot = gs_rot[0];
    fs_color = gs_color[0];    
    gl_Position = gl_in[0].gl_Position + vec4( 0.2, -0.2, 0.0, 0.0);
    EmitVertex(); //< emits all params above!

    fs_pos = gs_pos[0];
    fs_size = gs_size[0];
    fs_rot = gs_rot[0];
    fs_color = gs_color[0];    
    gl_Position = gl_in[0].gl_Position + vec4(-0.2,  0.2, 0.0, 0.0);
    EmitVertex(); //< emits all params above!

    fs_pos = gs_pos[0];
    fs_size = gs_size[0];
    fs_rot = gs_rot[0];
    fs_color = gs_color[0];    
    gl_Position = gl_in[0].gl_Position + vec4( 0.2,  0.2, 0.0, 0.0);
    EmitVertex(); //< emits all params above!

    EndPrimitive();

}

最后是几何体着色器。


# version 410

// the inputs to the fragment shader would have been interpolated
// across the geometry primitive emitted by the GS. 
layout (location = 0) in vec2 fs_pos;
layout (location = 1) in vec2 fs_size;
layout (location = 2) in float fs_rot;
layout (location = 3) in vec4 fs_color;

out vec4 FragColor;

void main()
{
    FragColor = fs_color;
}

相关问题