So I was reading "The Official OpenGL Guide" and in a section where they taught material lighting, they suddenly used the "flat" qualifier for an input variable in the fragment shader.
I google'd the matter and all I came up with was "flat shading" and "smooth shading" and the differences between them, which I cannot understand how it is related to a simple "MatIndex" variable.
here's the example code from the book:
struct MaterialProperties {
vec3 emission;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
// a set of materials to select between, per shader invocation
const int NumMaterials = 14;
uniform MaterialProperties Material[NumMaterials];
flat in int MatIndex; // input material index from vertex shader
What is this all about?
In the general case, there is not a 1:1 mapping between a vertex and a fragment. By default, the associated data per vertex is interpolated across the primitive to generate the corresponding associated data per fragment, which is what smooth shading does.
Using the flat
keyword, no interpolation is done, so every fragment generated during the rasterization of that particular primitive will get the same data. Since primitives are usually defined by more than one vertex, this means that the data from only one vertex is used in that case. This is called the provoking vertex in OpenGL.
Also note that integer types are never interpolated. You must declare them as flat
in any case.
In your specific example, the code means that each primitive can only have one material, which is defined by the material ID of the provoking vertex of each primitive.
It's part of how the attribute is interpolated for the fragment shader, the default is a perspective correct interpolation.
in the GLSL spec section 4.5
A variable qualified as flat will not be interpolated. Instead, it
will have the same value for every fragment within a triangle. This
value will come from a single provoking vertex, as described by the
OpenGL Graphics System Specification. A variable may be qualified as
flat can also be qualified as centroid or sample, which will mean the same thing as qualifying it only as flat
Integral attributes need to be flat.
You can find the table of which vertex is the provoking vertex in the openGL spec table 13.2 in section 13.4.