Over the last few years I’ve had a lot of people ask me how I was achieving the shading in my game. Originally I was using the method outlined by Tom Looman here to retrieve the dynamic shadow information and use it within the material editor, however Epic broke this back in 4.20 and onward, and even when it worked it was a buggy hacky mess. I’ve spent the last couple months digging into the horrible undocumented depths of Unreal’s shader system to go and achieve what I was doing before, but “properly” this time around. Here are the results.
I’ve exposed several shadow properties that I require for my project, they include the offset of Unreal’s light vector shadows, the hardness of the shadow, and the colour of the shadow. The latter of which can be used to do all kinds of ridiculous things, like this…
…but I just use it to make sure that the colour of a shadow always complements the colour of the light, and surface nicely.
Subsurface scattering also works, and has been slightly modified to work with the light levels I (and I imagine anyone else using this) would be working with.
(ignore the garbage gif compression)^
Left character is without, right is with.
Additionally, I’ve also added a control for dynamic shadow opacity. I use it on my character’s faces to eliminate dynamic shadows and only leave the Vector based shadows. I only use this on my character’s faces since they have edited normals to detach shading from the actual shape of the geometry, and dynamic shadows ruin this illusion.
**Limitations & Known issues:
Only Forward Rendering** is supported. Deferred shading is NOT supported.
Lightmaps aren’t supported at the moment, but I’'m interested in looking into integrating them in the future.
Shader Complexity viewmode doesn’t work correctly. I don’t know if this is related to my changes or not.
How it all works:
Most of this works just as it does in vanilla Unreal, the important bits are:
Shadow Range = this controls the softness of light vector shadows 0 is hard 1 is completely soft.
Specular/Roughness = Unchanged, but you probably want to set it to 0/Fully Rough respectively unless you’re making a material that utilizes reflections in some form or another.
Shadow Colour = Colour of the pixel when in shadow. In vanilla Unreal, shadow colour is multiplied by base colour to get your result, however here the colour when in shadow is entirely decoupled from base colour. This allows you a lot of freedom since you can quite literally put whatever you want here. You can do the above Nicholas Cage effect, make shadows brighter than unshadowed areas, or… do what I do and multiply my shadow colour by my base colour. (probably that one tbh)
Shadow Properties = Blue Channel is Vector Shadow Offset. Green Channel controls whether dynamic shadows are included in the shadow (1= Light Vector Shadows Only, 0= normal behaviour), Red channel is dynamic shadow range.
Ambient Occlusion = Permanent shadows.
For the sake of simplicity, this shading model hijacks the default lit shading model, so there’s no faffing about with changing the shading model for every single material you make, and you can use the default shading models (like subsurface) without issue (I hope, I haven’t tested anything other than subsurface :> ). The downside of this is that if you need the unmodified Default Lit shading model in addition to this you’ll have to put in the extra footwork of segregating my changes off into its own shading model.
Download & Getting Started:
You can find my repository here: https://github.com/envieous/UnrealEngine-SelShader
Before you ask why you got a 404 after clicking that link, read this: Unreal Engine 4 on GitHub - Unreal Engine
There’s a few changes that need to be made right from the get go to make this work in the way I intend it to.
You can either download the example project I’ve made here, or make these changes yourself from scratch.
First, in project settings, enable forward shading.
next, disable static lighting.
For point/spot lights to work correctly inverse square falloff needs to be disabled.
The rest of these are optional, but chances are if you’re using this you’ll probably want to do these too.
Disable auto exposure.
In your post process set exposure compensation to 0
In your directional light set it to moveable and give it an intensity of 1, the goal of this shading model is for colour values to be what you put in is what you get, and this results in that.
It’s also likely that if you’re using this you probably don’t want any sort of glossiness effects in most of your materials, so consider enabling this in materials you use.
Follow/Support this project:
& if you like this and want to support further development of this shading model (and any other useful stylized rendering stuff I happen to make), you can donate to my Patreon by clicking the button below.
Tom Looman for his Dr Facilier shadow demonstration that I used initially as the basis for my shading system.
Doomfest and Arnage, for their custom shading models. I studied a lot of their changes to figure out what was going on in Unreal’s USF files.
FelixK and Matt Hoffman for their articles on creating a custom shading model in Unreal. These articles despite being dated were still incredibly helpful for figuring all this out.