Search Unity

Flat shader

Discussion in 'Shaders' started by Dubmulik, Sep 30, 2014.

  1. Dubmulik

    Dubmulik

    Joined:
    Sep 30, 2014
    Posts:
    5
    I am trying to achieve this kind of art style: http://fc06.deviantart.net/fs70/i/2013/194/8/a/low_poly_landscape_by_error_23-d6danrj.png

    I found this tutorial: http://gamedevelopment.tutsplus.com...t-with-flat-shaded-3d-in-unity--gamedev-12259 and did what it said to achieve the look I wanted, but it splits the vertices and I end up with 5-6 times more vertices than the model originally had. This was not a problem in beginning, but now that I have to loop over vertices in code and do stuff to them, it is starting to be too much.

    So I figured that I need flat shader to achieve what I want and still keep the vertex count low. Now the problem is that I can't find any shaders that do that, and now I'm not even sure if it is possible to do with a shader. Can anyone point me in right direction?
     
  2. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Well, here's the thing. The GPU takes vertex color data from each vertice, so say you have a triangle, it has 3 corners, and thus needs 3 colors. In order to get the `flat` look, each color at each vertex has to be the same. If they aren't the same, the hardware will interpolate between the colors across the triangle and you'll get `gouraud shading` ie smooth shading, which you apparently don't want. This also means you have to treat each triangle as a totally separate triangle, with its own 3 vertices, so that you can attach 3 of the same color to it.

    The only way to SHARE vertices, so e.g. on vertex could belong to a few triangles where they intersect, and where you can move that vertex and have them all update together, yet still have flat shaded colors on a per-triangle basis, you're going to have to be able to store multiple color values at each vertex, and have some way to choose which of them is applied, plus calculate your own coloring of the triangle's fill. Sort of gets tricky, trying to store data in fields that aren't designed to hold colors well and then trying to get specific triangles to use specific sets of values.

    You could possibly sort of fake it with indexed color, instead of storing RGBA values at the vertex representing one color, let each color component represent one triangle and store the index of that triangle's color. Then you need a palette lookup. But also you need a way to tell which triangle uses which index, so would have to store some other per-vertex values or something.. not straightforward.

    If you want the flat-shading you really are mostly stuck with having each triangle be totally separate and not sharing vertices at all.
     
  3. mholub

    mholub

    Joined:
    Oct 3, 2012
    Posts:
    123
    I used nointerpolation HLSL modifier http://msdn.microsoft.com/en-us/library/windows/desktop/bb509668(v=vs.85).aspx
    in one project with flat shading.

    It gives you not exactly correct shading (because nointerpolation means — take value from first vertex in triangle instead of averaging three vertices), but it was ok for our needs.

    Big downside is — as far as I know it is available only in DX11 backend, because only with DX11 Unity uses microsoft hlsl compiler which supports this modifier instead of Nvidia Cg.

    GLSL contains same feature as flat interpolation modifier. It is OpenGL 3.2+ and OpenGL ES 3.0+.
    http://www.geeks3d.com/20130514/opengl-interpolation-qualifiers-glsl-tutorial/
     
  4. DavidSWu

    DavidSWu

    Joined:
    Jun 20, 2016
    Posts:
    183
    The nointerpolate modifier works for GLES and DX in current Unity builds.