“flat” qualifier in glsl?

2019-03-28 08:12发布

问题:

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?

回答1:

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.



回答2:

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.