In general, there is no 1: 1 mapping between a vertex and a fragment. By default, the corresponding data to the vertex is interpolated by primitive to generate the corresponding related data for each fragment, which makes smooth shading.
Using the flat keyword, interpolation is not performed, so each fragment generated during the rasterization of this particular primitive will receive the same data. Since primitives are usually defined by more than one vertex, this means that in this case only data from one vertex is used. This is called the calling vertex in OpenGL.
Also note that integer types are not interpolated. You must declare them as flat anyway.
In your specific example, the code means that each primitive can have only one material, which is determined by the material identifier of the calling vertex of each primitive.
source share