Today I’m continuing the breakdown of my shaders based on work by Owakita. Here’s part three!
I’ve written a number of posts breaking this down, and these can be found here:
Post Process Material
The aim of the post process was to create an outline around the objects, provide a grainy look and tint the screen color.
There were two approaches I considered for this. One was the kernel based edge detection I used on a project a couple years back, and another was the simpler sampling depth offset technique found in the UE4 stylised rendering example.
Ultimately I went for Epic’s approach, as while it may have been slightly more expensive for the amount of times it sampled depth, it was far simpler to setup and read later down the line. For this project I was really focused on the aesthetic over performance or tech, but I do still like to consider these things.
Determining Line Width
I started off by creating a single line on one side, by by getting the screen uv and offsetting it. I then multiplied this by screen texel size so the offset appears to be the same width, regardless of screen resolution.
Subtracting one channel of this value from the scene depth will give a single line edge, but we want an edge on all sides!
Creating An Outline On All Sides
I then split this offset into its U and V parts and multiply each by minus one, leaving us with four sets of offset UVs, as seen in the image below. These are then used to sample scene depth, which creates four different samples of the depth, all with a slight offset in one direction.
Subtracting these from the initial scene depth then adding them together leaves us with a nice combined outline!
Depth Based Line and Wireframe Fix
With this approach, we start to get the internal wireframe being outlined at distance. As a fix, we take the scene depth, divide it, then take one minus this (as UE4’s depth is flipped) then clamp it. This is the multiplied with the outline. This lowers the outline amount for these faces.
I later added something very similar to the initial outline calculation, where this was multiplied with the result of the texel size multiplier. What this did was take the depth and as the object gets further away, reduces the size of the line. This allowed me to not lose detail at distance and stopped blobby looking outlines.
Putting It All Together
One this outline is created, it is used as the alpha to lerp between the line color and the scene color. Here I’ve multiplied the scene color with a texture and color to add a bit of grain and color tinting.