Original Post
GLSL newbie question: how do pass per-face data to a GLSL geometry shader? I'm targeting GLSL 1.5.
What I'm trying to do specifically is decide whether to use the vertex normals or generate a face normal (via the cross product) for each face in the object. I have this working across the entire object via a uniform variable (i.e. toggle between smooth and flat shading); however, I'd like to pass a per-face flag to allow finer grain control. Is there some way I should be using gl_PrimitiveIDIn to accomplish this? I'm fairly confident in how to pass down per-vertex arrays of data and using uniforms, but I'm not sure of the middle ground of per-face data works. I realize I could duplicate vertices between faces and simply pass per-face data as redundant per-vertex data, but I'd prefer not use that approach if there are other options.
For reference, below is a simplified version of the geometry shader I currently have that uses a uniform for the whole object rather than per-face basis. In other words, what I'm trying to do if replace that "unifFlatNormals" variable with a per-face variable.
[source lang="cpp]
uniform int unifFlatNormals;
in vec3 geomVertexEc[]; // Vertex position in eye coordinates from the vertex shader
in vec3 geomNormalEc[]; // Vertex normal in eye coordinates from the vertex shader
varying out vec3 fragNormalEc;
vec3 computeNormal (vec3 v0, vec3 v1, vec3 v2)
{
vec3 a = v2 - v1;
vec3 b = v1 - v0;
return normalize( cross (b, a) );
}
void main()
{
vec3 n = computeNormal(geomVertexEc[0], geomVertexEc[1], geomVertexEc[2]);
for (int i = 0; i < gl_VerticesIn; i++)
{
gl_Position = gl_PositionIn;
if (unifFlatNormals == 1)
fragNormalEc = n; // Replace the per-vertex data with a uniform normal across the entire primitive
else
fragNormalEc = normalize(geomNormalEc); // Pass the per-vertex data directly
EmitVertex();
}
EndPrimitive();
}
[/source]
What I'm trying to do specifically is decide whether to use the vertex normals or generate a face normal (via the cross product) for each face in the object. I have this working across the entire object via a uniform variable (i.e. toggle between smooth and flat shading); however, I'd like to pass a per-face flag to allow finer grain control. Is there some way I should be using gl_PrimitiveIDIn to accomplish this? I'm fairly confident in how to pass down per-vertex arrays of data and using uniforms, but I'm not sure of the middle ground of per-face data works. I realize I could duplicate vertices between faces and simply pass per-face data as redundant per-vertex data, but I'd prefer not use that approach if there are other options.
For reference, below is a simplified version of the geometry shader I currently have that uses a uniform for the whole object rather than per-face basis. In other words, what I'm trying to do if replace that "unifFlatNormals" variable with a per-face variable.
[source lang="cpp]
uniform int unifFlatNormals;
in vec3 geomVertexEc[]; // Vertex position in eye coordinates from the vertex shader
in vec3 geomNormalEc[]; // Vertex normal in eye coordinates from the vertex shader
varying out vec3 fragNormalEc;
vec3 computeNormal (vec3 v0, vec3 v1, vec3 v2)
{
vec3 a = v2 - v1;
vec3 b = v1 - v0;
return normalize( cross (b, a) );
}
void main()
{
vec3 n = computeNormal(geomVertexEc[0], geomVertexEc[1], geomVertexEc[2]);
for (int i = 0; i < gl_VerticesIn; i++)
{
gl_Position = gl_PositionIn;
if (unifFlatNormals == 1)
fragNormalEc = n; // Replace the per-vertex data with a uniform normal across the entire primitive
else
fragNormalEc = normalize(geomNormalEc); // Pass the per-vertex data directly
EmitVertex();
}
EndPrimitive();
}
[/source]