A shader applied to any object to make it look as it has been painted. The shader only uses a "paint texture", a grayscale texture used for the brush strokes effect, and a gradient texture, used to change the paint color based on lighting. The project also features custom post processing effects, making the screen looks like a painting canvas, although the paint effect can be used only on object separately, without any post processing effect.
One of the benefits of this implementation is that the shader can use triplanar projection for the paint effect, meaning UV unwrapping is not needed for the meshes (which can be useful if using meshes found online, or to gain some time when using custom meshes).
Note: the meshes used in the project are free resources I found online! They're not meant to be perfect or reusable, but are only here to show actual implementations of the shader.
The shader used is a fragment shader using custom lighting computation; getting the lighting data before actually applying it is a good way to tweak them for the desired painted effect. In order, here are the steps the shader follows to render an object.
Standard diffuse material: as a reference point, here's how the demo object looks like before anything done:
Lambert lighting: the most important part of the effect is the lighting calculation, that will be crucial when applying color afterward. A simple Lambert is used, with some control to remap the values, and decrease the shadow intensity (which does not make much sense for a PBR perspective, but is useful here since we want a nice looking painted effect).
Specular: a specular highlight can be added if needed, depending on the object.
Fresnel: a Fresnel effect can be added if needed, depending on the object. On an apple, it may seem quite strange, but at least the effect is very readable.
Brought together, all of the effects detailed above give this result:
Gradient map: using the lighting data, a color gradient is applied across the object. Note that the gradient is applied to all of the mesh, meaning that if some parts of it should use a different gradient, than they should be split into separate meshes. Here, the apple's tail should not use the same color as the apple itself (this is fine for the demo purpose, and also to show a restriction of the shader).
Ambient color: ambient color of the scene is applied to the darker parts of the object, tinting the shadows.
Light color: the light color is applied to the brighter parts of the objects, tinting the parts that are exposed to light, and leaving the shadows unchanged.
The effect is now done, although the cast shadow still looks bad. To fix this, the ground needs to also use a painted material.
Some custom post processing effects are implemented, to enhance the overall painted effect.
Base image: consider this image as the base rendered image.
Distortion: using a noise texture, the screen can be distorted to mimic the flaws of brush strokes. Ideally, a Kuwahara filter could be implemented, but I didn't take the time to look at it (may be something to do in the future).
Sobel outline: an outline filter can be added, to add some sort of drawn lines. May not look good with all scenes, but still a nice addition to experiment with if needed.
Canvas texture: the most important effect, applying a painting canvas texture with a custom mask on the screen borders. The mask has been hand drawn and is not driven by material parameters, it's a simple grayscale texture.