Flat shading tips/techniques

Disclaimer: I’m a total newbie when it comes to shaders, materials and art in general, so please forgive misunderstandings/errors.

Recently there’s been a fair amount of interest in a flat shaded style (often known as ‘low poly’ style, though that usually has a different meaning in the context of game art). I myself am experimenting with it because I think it looks nice, it makes creating art assets simple for a non-artist like me, and it makes it easier to get high performance (I’m experimenting with Oculus Rift development where this is critical).

I already have some reasonably nice results coming out of UE4 with this style, but I’d like to learn how to do more. For example, at the moment I’m exporting models from Blender with multiple materials applied to a single mesh (each material covering separate parts of the mesh). The materials are just simple solid diffuse colours, which gets me results that look a bit like the trees at the top of this article.

I was wondering if anyone had any tips on getting more colour variation across my meshes, a bit like the background in this example, where the faces can be given different colours, whilst maintaining that flat shaded look. Do I have to manually texture my meshes? Or is there some way to do this with vertex colour painting?

Any other tips on working in this style are much appreciated!

Multiple materials or applying textures are overkill. If you’re looking for a flat shaded style, then it’s more efficient to work with vertex colors or normals.

You can do a color shift by multiplying the vertex color by a random amount. Here’s a quick example with a solid blue ball mesh:

An alternate method is to actually tilt the vertex normals a bit. This will dynamically change the highlights as the light angle shifts so I think it is a bit nicer:

All you need to do is import a piece of flat-shaded geometry and paint the vertices whichever colors you want. It might be a bit more efficient to pre-process your meshes to randomly vary the color or normals, but using a UE4 material will let you import any mesh and use UE4’s painting tools to paint it. And you’d have to find or write a plugin that would do it for you in Blender (or Maya, etc.). It wouldn’t be that complicated if you had experience writing Blender plugins, but I’ve never tried it.

The weakest part of these materials I posted is probably the random number generation which I just created on the spot by doing a bit of math on the world-space normal vector. So any faces that have the exact same angle will end up with the same random number, and the number may not actually be particularly random (though I didn’t see any really obvious visual patterns in it). It could probably use a bit of tweaking.

Any calculations that you feed into the customized UVs are done per-vertex instead of per-pixel so it is usually better to do as much there as possible (unless you have a lot of really complex meshes covering only a few pixels–which you should never have anyway).

Edit: One quick mistake I realized after posting: there should be a “Transform: World to Local” node right after the first “VertexNormalWS” node that feeds into the random number generator. That way you will get consistent variation even when the object rotates. Though, it may look okay and be a bit faster without it.

Can you update this?

This thread is from 2014, but it uses Custom UVs and someone recently mentioned to me that to achieve a true flat look, that’s the way to go.

However, I’m wondering if this example is now outdated, because I tried it and it doesn’t seem to behave any different than the “standard” DDX x DDY or split vertex imports…

(The purple sphere on the bottom is using the above example, yet I still see soft shading and also per-pixel reflections.)

Yes, 2 years later. Same Problem.
Android still can’t use DDX DDY so we can’t get a flat shaded render.
Actually we are spliting all polygons but the result is a extra number of vertices. 4 more vertices…
So i was digging the net to find a way to achieve this falt render and arrived here.
Can anybody repost this vertex orientation hack technique? or explain a bit more?
Thank you