4
\$\begingroup\$

I'm trying to visualize the face normals for a mesh, using the geometry shader to generate lines represeting the normal vectors. My intention was to draw that line from the triangles centroid, extenting a certain amount in the normal's direction.

This is the vertex shader's code :

#version 450 core

layout (location = 0) in vec3 vs_in_pos;
layout (location = 1) in vec3 vs_in_normal;
layout (location = 2) in vec2 vs_in_texc;

out VS_OUT_GS_IN {
    layout (location = 0) vec3 pos;
    layout (location = 1) vec3 normal;
    layout (location = 2) vec2 texc;
} vs_out;

void main() {
    gl_Position = vec4(vs_in_pos, 1.0f);
    vs_out.pos = vs_in_pos;
    vs_out.normal = vs_in_normal;
    vs_out.texc = vs_in_texc;
}

This is the geometry shader's code :

#version 450 core

layout (row_major) uniform;
layout (triangles) in;
layout (line_strip, max_vertices = 2) out;

in VS_OUT_GS_IN {
    layout (location = 0) vec3 pos;
    layout (location = 1) vec3 normal;
    layout (location = 2) vec2 texc;
} gs_in[];

out GS_OUT_PS_IN {
    layout (location = 0) vec4 color;
    layout (location = 1) vec3 pos;
} gs_out;

layout (binding = 0) uniform transform_pack {
    mat4 model_view_projection;
};

uniform float normal_length;
uniform vec4 start_point_color;
uniform vec4 end_point_color;

void main() {

    const vec3 avg_normal = normalize(
        gs_in[0].normal + gs_in[1].normal + gs_in[2].normal);

    const vec3 triangle_centroid =
        (gs_in[0].pos + gs_in[1].pos + gs_in[2].pos) / 3.0f;

    {
        gl_Position = model_view_projection * vec4(triangle_centroid, 1.0f);
        gs_out.color = start_point_color;
        gs_out.pos = triangle_centroid;
        EmitVertex();
    }

    {
        const vec3 end_pt = triangle_centroid + avg_normal * normal_length;
        gl_Position = model_view_projection * vec4(end_pt, 1.0f);
        gs_out.pos = end_pt;
        gs_out.color = end_point_color;
        EmitVertex();
    }

    EndPrimitive();
}

My problem is that the line representing the face normal has the origin at one of the triangle's vertices (not the centroid).

If, however, I change this line

const vec3 triangle_centroid =
    (gs_in[0].pos + gs_in[1].pos + gs_in[2].pos) / 3.0f;

with this line

const vec3 triangle_centroid = 
    (gl_in[0].gl_Position.xyz + gl_in[1].gl_Position.xyz 
    + gl_in[2].gl_Position.xyz) / 3.0f;

the line representing the normal has the origin at the centroid (as it should).

But I really have no ideea why the first approach does not produce the correct result.

Some screenshots :

first method (wrong):

first method (wrong)

second method (correct): second method (correct)

\$\endgroup\$
1
\$\begingroup\$

Ok so I've discovered that if I remove the layout qualifiers from the input/output blocks, like this

out VS_OUT_GS_IN {
     vec3 pos;
     vec3 normal;
     vec2 texc;
} vs_out;

and like this in the geometry shader

in VS_OUT_GS_IN {
     vec3 pos;
     vec3 normal;
     vec2 texc;
} gs_in[];

it produces the expected results.

But why does it not work when the explicit layout qualifier is used for the individual members of the block ?

\$\endgroup\$
1
\$\begingroup\$

Although according to the OpenGL standard you should be allowed to specify whichever location you want, some drivers have specific locations for legacy uses.

Specifying locations may cause conflicts with those.

For example: https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php

NVidia hardware indices are reserved for built-in attributes:

gl_Vertex 0

gl_Normal 2

gl_Color 3

gl_SecondaryColor 4

gl_FogCoord 5

gl_MultiTexCoord0 8

gl_MultiTexCoord1 9

gl_MultiTexCoord2 10

gl_MultiTexCoord3 11

gl_MultiTexCoord4 12

gl_MultiTexCoord5 13

gl_MultiTexCoord6 14

gl_MultiTexCoord7 15

\$\endgroup\$
  • \$\begingroup\$ This is only a consideration if you're mixing generic attribs with legacy attribs; you can't do glVertexPointer and glVertexAttribPointer(0), for instance. \$\endgroup\$ – Maximus Minimus Feb 1 '17 at 17:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.