Hello fellow Unreal Engine users!
This is not really a tutorial in that I guide you through every single step. Instead I’m going to throw my Material asset (including comments) at you for everyone to use, adjust and play around with.
Note that the following images were captured using the Vehicle Game Sample/Template/Demo which is made by Epic Games. I’ve only created the post process material and applied it to their content/game.
So before I’ll give you the material setup, you can see the post process effect in action if you like.
Or just enjoy these postcards, err… I mean screenshots.
So here is the actual material I created:
As you can see it does not need many nodes. This is because most stuff is hidden in the Custom Node.
This node uses three inputs which you’ll have to set up. “offset”, “UV” and “scale”. The Output Type is CMOT Float 1. The following is the code used for that node:
//kernel size
int sizeX = 5;
int sizeY = 5;
//offset added to all uvs to get from the center to the corner
MaterialFloat2 baseOffset = MaterialFloat2(-sizeX/2.0f, -sizeY/2.0f) * offset.rg;
//sample the world normal from the GBuffer
float4 baseNormal = SceneTextureLookup(UV, 8);
//dot product for two normalized vectors ranges between -1.0f to 1.0f
//we're going to search the smallest value so initialize to something larger
float minDot = 10.0f;
for (int i = 0; i < sizeX; ++i)
{
for (int j = 0; j < sizeY; ++j)
{
//calucalte clamped uvs
float2 uvs = min(max(UV + baseOffset * scale + i * offset.r * scale.r * float2(1.0, 0.0f) + j * offset.g * scale.g * float2(0.0, 1.0f), float2(0.0f, 0.0f)), float2(1.0f, 1.0f));
//sample world normal from the GBuffer at the new position
float newDot = dot(baseNormal, SceneTextureLookup(uvs, 8));
//if smaller than our current value
if (newDot < minDot)
{
//use the new value
minDot = newDot;
}
}
}
//return smallest dot product in this region
return minDot;
There are a few more things you’ll need to set up before you’re ready to go. The first is to set the Blenable Location for the main material node to “Before Tonemapping”. The second step is to create a Material Instance from this Material (you can right-click it and choose “Create Material Instance” in the Content Browser) which allows you to control the edge thickness as well as how fast an edge is detected. Finally you just have to make use of the Material Instance for example by adding it to the Blendables of a PostProcessVolume.
I did not spend alot of time improving it, so it has a few issues. If used with TXAA some edges flicker. On the other hand some edges look worse without TXAA.
It’s been over a year since I initially created this with 4.2 so some things may be different and require some adjustments in other versions.