I want to know what's the most efficient way to implement low poly style flat shading. I have checked this post, however the options listed in the page don't feel perfect to me. I list them below for reference.

  1. Duplicate each vertex so that same vertex can associate with a different normal.
  2. Use flat to disable interpolation.
  3. Evaluate normal at fragment shader using dFdx and dFdy.

To me, option 1 wastes some vertex attributes, since duplicate vertices have the same position. Option 3 perform unnecessary calculation on every fragment even though the normal should all be the same. Option 2 feels conceptually right to me, but I don't know what normal value should be saved at each vertex. This is also the approach hinted in book 'Real Time Rendering' (4e, p120).

My question is: what's the best way to implement it? Given so many commercial games used this style, I want to know how it is typically implemented by real world games?

  • 2
    \$\begingroup\$ Remember that modern video cards are optimized to handle highly realistic games pushing hundreds of thousands or even millions of polygons in total each frame. Even mobile chips can chew through an impressive number now. If you're working in a low-poly style already, the splitting of vertices where the normals differ is unlikely to negatively impact your performance. The vertex workload is simply not the hard part of the rendering process in a style like that, compared to what the hardware can handle. \$\endgroup\$
    – DMGregory
    Commented Aug 27, 2019 at 23:16
  • 2
    \$\begingroup\$ Have to agree with with DMGregory, you will find that the Vertex Shader is one of the least stressed parts of the pipeline (unless you are doing alot heavy calculation up front). With your flat shading, you actually have to treat each face discreetly, therefore you have to have normals specific to each face. Indice based rendering becomes less useful in these situations, its best use where the same vertex shares the same normal, tangent, position etc, and that the GPU pipeline knows that this face has been computed once. Just go for the simplest approach for now, revisit if performance lags \$\endgroup\$
    – ErnieDingo
    Commented Aug 27, 2019 at 23:21
  • \$\begingroup\$ Absolutely agreed, none of these are likely to be performance problems. You could even say option 4 is to put each triangle through a geometry shader and calculate the normal there, and it would still run fine for a low poly workload. \$\endgroup\$ Commented Aug 28, 2019 at 4:33
  • \$\begingroup\$ Thank you for all the answers, I guess any of the approaches will work then. But I still want to know what approaches real world games generally choose? \$\endgroup\$
    – Rui Liu
    Commented Aug 28, 2019 at 19:26


You must log in to answer this question.

Browse other questions tagged .