6

I've written a very simple pass-through geometry shader. My input primitive is points and output primitive is also points. I also want to forward the color and normal from vertex shader to fragment shader through geometry shader. The shaders are compiled and linked flawlessly but the final color is very weird. I think there is something wrong with this forwarding. Can anyone point out the problem? Here are my shaders:

Vertex shader:

#version 330 compatibility

struct vData
{
    vec3 normal;
    vec4 color;
};

out vData vertex;

void main()
{
    vertex.normal = gl_NormalMatrix * gl_Normal;
    vertex.color = gl_Color;
    gl_Position = ftransform();
}

Geometry shader:

#version 330

layout (points) in;
layout (points) out;
layout (max_vertices = 1) out;

struct vData
{
    vec3 normal;
    vec4 color;
};

in vData vertices[];
out vData frag;


void main()
{
    int i;
    for(i = 0;i < gl_in.length();i++)
    {
        frag.normal = vertices[i].normal;
        frag.color = vertices[i].color;
        gl_Position = gl_in[i].gl_Position;
        EmitVertex();
    }
    EndPrimitive();
}

Fragment shader:

#version 330

struct vData
{
    vec3 normal;
    vec4 color;
};

in vData frag;

void main()
{
    gl_FragColor = frag.color;
}
Partha Bera
  • 448
  • 1
  • 3
  • 9
  • 3
    Stop passing structs between shader stages. Yes, I know it's technically allowed by the standard. But nobody uses that, so it's not well-tested by IHVs. If you need grouping of inputs and outputs, [use interface blocks](http://www.opengl.org/wiki/Interface_Block_%28GLSL%29). – Nicol Bolas Feb 16 '13 at 13:12
  • Thank you for your response! I should follow that! – Partha Bera Feb 18 '13 at 04:30
  • @NicolBolas I just have a question about passing structs... your post is very old, so I would like to ask you if you would still say: "stop passing structs between shader stages" or is this hint outdated? Thanks! – Thomas Sep 13 '21 at 09:11

1 Answers1

18

I figured this out! the in/out variables must have same name i.e. vertices[] in geometry shader should be vertex[]. That's it!

My refined and working code goes as follows:

Vertex shader:

#version 330 compatibility

out vData
{
    vec3 normal;
    vec4 color;
}vertex;

void main()
{
    vertex.normal = normalize(gl_NormalMatrix * gl_Normal);
    vertex.color = gl_Color;
    gl_Position = ftransform();
}

Geometry shader:

#version 330

layout (points) in;
layout (points) out;
layout (max_vertices = 1) out;

in vData
{
    vec3 normal;
    vec4 color;
}vertices[];

out fData
{
    vec3 normal;
    vec4 color;
}frag;    

void main()
{
    int i;
    for(i = 0;i < gl_in.length();i++)// gl_in.length() = 1 though!
    {
        frag.normal = vertices[i].normal;
        frag.color = vertices[i].color;
        gl_Position = gl_in[i].gl_Position;
        EmitVertex();
    }
    EndPrimitive();
}

Fragment shader:

#version 330 compatibility

in fData
{
    vec3 normal;
    vec4 color;
};

void main()
{
    gl_FragColor = frag.color;
}

Happy coding!

Partha Bera
  • 448
  • 1
  • 3
  • 9