With this tutorial we are going to add more effects and the treatment of the occluded parts of the object that has the outline effect of the previous tutorial.
In the previous tutorial we added the outline effect to some objects of a simple scene. This outline could be seen even when the object was hidden, partially or completely, by other object.
To determine when the object is occluded we need to take the difference between the custom depth and the scene depth. We can add a parameter to control the alpha value of the internal shape of the outline.
FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(UV, false); return clamp(ceil(ScreenSpaceData.GBuffer.CustomDepth.r - ScreenSpaceData.GBuffer.Depth.r), 0, 1) * OcclusionAlpha;
Since engine version 4.19, the ScreenPosition node returns the ViewportUV instead of Buffer UV so we need to call ViewportUVToBufferUV to convert from viewport to buffer position. If you are using an engine version >= 4.19 you must use this code instead of the above HLSL code
FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(ViewportUVToBufferUV(UV), false); return clamp(ceil(ScreenSpaceData.GBuffer.CustomDepth.r- ScreenSpaceData.GBuffer.Depth.r), 0, 1) * OcclusionAlpha;
This code must be added to a custom node expression
Since engine version 4.20 we must check if we are using SceneTexture properties ( like the access to the property CustomDepth of GBuffer), to avoid compilation errors we need to add the next preprocessor directive
1 2 3
#if SCENE_TEXTURES_DISABLED return 0; #endif
So, if you are using an engine version >= 4.20, you must use this code instead of the above code
1 2 3 4 5
#if SCENE_TEXTURES_DISABLED return 0; #endif FScreenSpaceData ScreenSpaceData = GetScreenSpaceData(ViewportUVToBufferUV(UV), false); return clamp(ceil(ScreenSpaceData.GBuffer.CustomDepth.r- ScreenSpaceData.GBuffer.Depth.r), 0, 1) * OcclusionAlpha;
But we need to limit this effect to the object shape, we can take this shape using the Custom stencil values of the image. We can add the outline to this shape too.
Now, putting all together:
We can add more features like more color options, or glow effects.
We can replace our color node with a color switch, using the stencil value we can choose the color that will be applied to the outline object
The code inside de custom expression is a switch that returns the color associated to an index value.
1 2 3 4 5 6 7 8 9 10
float ColorIndex = ColorIndexInput; if( ColorIndex == 1 ) return Color1; else if( ColorIndex == 2 ) return Color2; else if( ColorIndex == 3 ) return Color3; else return Color3;
If we want to add more colors, we only need to add more inputs to the custom node and modify the code to add more if-clauses using the same pattern.
We can establish that values below the StencilFirstIndex parameter will disable the outline effect.
Final material overview:
Now we only need to change the stencil value to change the outline color
To achieve this effect we must multiply the color output by a value above 1.
With a value of 100 in the material instance we can obtain a nice glow effect.
Finally we can add a pulsating effect to the glow to do it more dynamic. Just multiply the color by a sine node connected to a Time node.
These have been some of the outline effect possibilities, we have a lot of combinations and more features can be added to this base effect.
Your imagination is the limit.
Support this blog!
For the past year I've been dedicating more of my time to the creation of tutorials, mainly about game development. If you think these posts have either helped or inspired you, please consider supporting this blog. Thank you so much for your contribution!