This is a UE5 version of my shading model for UE4 that I built for my military academy dating simulator/military warfare tactical rpg/tank washing simulator.
A fair amount of stuff has changed since the previous thread, including the first number in the engine version it’s for so may as well make a new thread to contain that information.
In summary, this shading model allows you to specify exactly what unreal displays in shadow and lit areas. This doesnt have to follow any sort of realistic lighting logic, you can create materials that are brighter in shadow than where they are actually lit. Whatever you put in the shadow colour pin is what is displayed in shadow.
Here is Nicholas Cage to demonstrate.
and some basic spheres
Here’s how it works.
Material and Lighting Setup
This Shading Model hijacks the default lit Shading Model.
Most of this works the same as stock Unreal.
Base Colour works the same as stock Unreal, however I do not use the colour of light actors on the shading side. So if you have a surface and you want to apply a light colour to it you need to multiply that onto the base colour on the material side. I might change this back later but I’m working on some effect ideas that require this kind of setup. It’s also a nonissue unless you want to use more than just a single directional light which isn’t a purpose this shading model is really geared towards.
Metallic is compressed into two inputs. One is shadow range, which controls how soft the shadow is. 0 is hard, 1 is full. The other is the influence of lightmaps on the surface. In levels containing lightmaps this second input is used to prevent materials from being affected either by lightmaps themselves or the volumetric lightmaps which can throw off the appearance of surfaces even if they themselves don’t contain any lightmap information. (I use this on characters for instance)
Set up metallic like so.
Custom Data 0 is Shadow Colour. This is what renders when a surface is in shadow.
Custom Data 1 isn’t used for anything but it is exposed and will write a single channel to the gbuffer so it can be used to provide information to a post process material.
All that is needed on the lighting front is a single white moveable directional light with an intensity of 1. You can affect the size of the shadow by raising/lowering this, but this value is what I use.
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
These changes aren’t explicitly required, but if you’re trying to achieve a look similar to mine this is how I’m doing it.
Disable exposure adjustment here.
You’ll also likely want to look at your other post process settings, bloom and vignette in particular and pick values you like.
The tonemapper in Unreal is notorious for washing out/desaturating/and just generally ruining your colours in the name of physical accuracy. I have disabled the tonemapper and Unreal now outputs colours very close to what is inputted.
If for some reason you actually want Unreal to tOnEmAp your colours you can undo this change by changing this line in PostProcessTonemap.usf
half3 OutDeviceColor = LinearColor.rgb;
half3 OutDeviceColor = ColorLookupTable(LinearColor);
Unreal also tonemaps UMG elements. I have no idea why ANYONE would desire this behavior, and unfortunately I can not remove this functionality without severely compromising the usability of the editor as it affects the ENTIRE editor UI as well.
For now the best way I’ve found to correct this is to create this material function to correct UMG colours.
This isn’t an ideal way of doing this and will probably cause problems, but it’s good enough for development, and can be removed at the end while also removing UMG tonemaping for the final build to achieve correct results.
To remove UMG tonemapping open SlateElementPixelShader.usf and comment out the lines:
OutColor = ApplyContrast(OutColor);
OutColor.rgb = GammaCorrect(OutColor.rgb);
I should probably mention Lumen. I’ve played with it a bit but it doesn’t seem feasible from a both a performance and art standpoint to utilize it in my project so if you want to use it I can’t really offer any suggestions or help, but if you make something cool with it in this shading model I’m very interested to see what people come up with.
I’ve also included some little… curiosities in DeferredLightPixelShader.usf.
If you uncomment
OutColor.rgb = Radiance.rgb;
and comment out
ShadowMask = smoothstep(0.5 - ShadowRange, 0.5 + ShadowRange, Luminance(Radiance));
OutColor.rgb = lerp(ShadowColour, PixelColour, ShadowMask);
Unreal will output lighting information only, effectively creating a lighting buffer that can be accessed by post process materials.
I’m not using this approach, but people interested in creating their own custom shading through post processes may find this interesting given the significant drawbacks of the traditional Scenecolour divided by diffuse colour to get a crude approximation of the lighting information approach. If you come up with something neat through this post it here.
This project has all the settings setup and contains further example content.
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.
I’m pretty sure that covers everything. Enjoy.
Also consider leaving a post and vote here in the off chance of getting Epic to make custom shading models not require wasting hours of everyone’s time building the engine from source just to enable a couple material pins.
Finally ,if you want to support my game and by extension this shading model, you can do so on Patreon here.