Van Gogh Shader

November 2024
  • Unity
  • HLSL
Project Repo

Overview

This is a custom surface and post process shader inspired by the iconic painting style of Van Gogh. I did this using various combinations of noise functions to add surface color, outlines, and a brush stroke distortion. The base color and outlines were done using Unities npr shader graph and the brush post process effect was done with a custom hlsl function. The scene was created using custom tree assets, and various free assets from online.

Reference Images

Screenshot 1
Wheat Field with Cypresses
Screenshot 2
Landscape from Saint-Rémy

Video Demo

Breakdown

Surface Shader

For this project I was trying to mimic the swirling painterly effect of Van Gogh. To do this, I started with a base toon shader, which was made using a discrete gradient. I then added a series of noises to deform the UVs of the surface, which I then used as the input for another noise. This distored the cutoff lines between the highlight, midtone, and shadow colors making the colors have a more swirly feel. On top of that I added some slight color variation using two passes of a worley noise where the UVs are multiplied by one Worley and then passed into the second one. This give the circular swirling pattern I was going for. Additionally, I could offset the UVs by a time variable allowing those swirls to move around and ripple. The colors and thresholds were all parameterized for easy customization.

Brush Stroke Post Process Shader

To get the main brush stroke effect, I added a full screen post process layer. This shader takes in our rendered scene and discritizes the entire thing into voronoi cells where the color of each cell is determined by the color of the fragment the voronoi point lies in. This by itself makes a mosaic like version of the scene. By combining this effectwith some layers of noise (using the same double Worley noise technique described above) I was able to rough up the edges of the voronoi cells, causing them to swirl togeather and creating a more brush like effect.

Outlines

To get an outline effect around the various objects, I started with a basic depth based approach. For each fragment, you compare its depth with the depth of neighboring fragments. The difference in depth between these fragments is then used as the alpha of a post process shader which overlays a parametrized color over the entire screen. If there is enough of a difference, it means we are on the vissible edge of an object or shape, and our difference will be large. This will color in just those edge fragments. Additionally, I offset the sampled neighboring fragments using a noise to get a non-uniform edge.

Screenshot 1
Full Shader Effect