23

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?

McLovin
  • 3,295
  • 7
  • 32
  • 67

2 Answers2

45

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.

nmr
  • 16,625
  • 10
  • 53
  • 67
derhass
  • 43,833
  • 2
  • 57
  • 78
  • 1
    Excuse me but what does "interpolation" mean in our context? English isn't my native language and when I try to get its translation in my language I get "interpolatsia", which is the same word. =[ – McLovin Dec 20 '14 at 15:12
  • 8
    @Pilpel: [interpolation](https://en.wikipedia.org/wiki/Interpolation) is a general concept you should make yourself familiar with when you want to do graphics. With interpolation, one usually has a set of data points and tries to generate values for inbetween the given data points. In this contex, we have per-vertex data and have to interpolate it per fragment. Imagine a triangle with color per vertex. For vertex A, we specify red, for vertex B, we specify green and for vertex C, we specify blue. Interpolation will generate smooth color gradients across the whole triangle. – derhass Dec 20 '14 at 16:48
6

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.

ratchet freak
  • 47,288
  • 5
  • 68
  • 106