Earlier this week I saw a really neat effect where @Sererena simulated the view-dependent shimmering of a foil card, fed by a smartphone accelerometer. This seemed like a good challenge to improve my material creation skills in UE4, so I gave it a go yesterday and came up with something I’m reasonably happy with. The view angle is controlled by WASD rather than the accelerometer since I was more focused on the material.
Download
You can download the assets and test project (built with Unreal Engine 4.15), licensed as CC0.
Construction
The material has 8 layers:
- Background
- Distant large stars
- Small stars / motes
- Near large stars
- Character foil outline
- Character
- Foil on character accents
- Card border
The foil character accent layer and the star layers all parallax as the view angle changes (shift around, with a larger shift for nearer layers, faking a sense of depth).
The foil layers (everything except the character) are colored by a lookup into a ‘holographic plate’ texture, using an ad hoc function of the tex coord, distance, and tilt amount.
The character accents layer is done with a color notch filter and one star layer, directly added to the character color (rather than lerping to it). This is the part I’m least happy with in the current implementation, but I’d need to test it with a real character to see exactly what I’d want to change.
The material is built using a bunch of material functions as building blocks to make it cleaner, but these aren’t meant to ‘stand alone’; there are lots of assumptions built into them about textures and parameter values.
I’m using a live capture of a 3D character instead of a 2D base, but after the capture Blueprint updates the render target, everything else is the same either way. The capture BP is an opaque box containing the character, a capture component, and a controlled light source. Even with setting the capture component to only capture the self actor and setting an aggressive culling distance, some ‘global’ things like atmospheric fog still render into it, so I had to use the mode that gave me depth in alpha rather than an opacity mask in order to discard it.
The outline is done with a Sobel edge detection filter on the thresholded depth from the character render target (which has depth as alpha). Rather than using a kernel of the adjacent texels, it uses texels 8 away to increase the width of the outline. If I were using 2D characters I’d probably skip the runtime Sobel filter and do that offline once into a mask texture.