Volume Texture support was added to Unreal Engine all the way back in version 4.21, and ever since I learned of this often overlooked feature I’ve been excited to integrate it into my VFX work. Finally my time has come.
In this tutorial we will be using a Volume Texture and an Exponential Height Fog Actor to create a volumetric energy pulse effect. Along the way we are going to explore how Volume Textures work, and look at some other interesting examples of how they can be used.
Download the Unreal project
This is the third part of my ongoing series Creating a Halo-inspired Bubble Shield for Unreal Engine 5.
If you would like to access to the source files from this series I would like to invite you to subscribe to my Patreon, where you will be able to download them alongside content from all current and future techarthub tutorials.
Throughout this tutorial I will be using some of the assets created in previous parts of my Bubble Shield series to demonstrate the effect, but they won’t be prerequisites to what we’ll be creating. This one is entirely standalone and will be incorporated into future tutorials as the series progresses.
What are Volume Textures?
Sometimes called 3D or Pseudo-Volume textures, Volume Textures are a method of storing 3D information within a 2D image. This texture can then be unpacked and interpreted by Unreal as a volume.
Volume Textures work by providing a series of 2D ‘slices’ of a 3D space. These slices are stored in rows, and the engine rebuilds the 3D volume by stacking them in order one on top of the other. Here is a video that I hope illustrates the concept.
The Volume Texture creation process is fascinating, and their potential (especially in VFX work) is huge. I’d like to jump straight into the tutorial as soon as possible, so this is as much of the theory as I think we’ll cover.
If you’d like more information on Volume Textures here are some amazing resources that really helped me understand the concept:
- How to create and use Volume Textures in UE4 | Unreal Engine Documentation
- Working with Volume Textures in Unreal Engine 4 | Overdraw
- Authoring Pseudo Volume Textures | Shaderbits
Accessing Volume Textures in Unreal Engine 5
Although they’ve been packaged within the engine files since version 4.21, you’ll need to enable the Volumetrics plugin to gain access to the sample Volume Textures. Jump into your plugins window and do a search for Volumetrics and it should come up.
Once that’s enabled and you’ve restarted your Editor, if you enable both Engine and Plugin Content in your Content Browser you’ll be able to search for the prefix VT_ to find them.
If you want to play around with their settings I highly recommend first duplicating these files and putting them in a folder of their own that’s outside of the Engine Content. Just in case.
Creating a Material for our Volume Texture
To create our rippling pulse effect we’re going to create an additive volume Material. The goal here is to use two Material Functions in tandem, one that generates a 3D spherical energy pulse, and another that will distort that pulse to create the effect of wispy smoke-like dissipation.
All together the Material will support a range of different pulse effects by modifying a number of parameters.
First things first, we’ll need to create some new assets:
- A Material named M_VolumetricPulse
- Two Material Functions called MF_SphericalPulse and MF_DistortWorldPosition.
This first function is responsible for creating a 3D pulse effect that will radiate outwards from the origin of the mesh to which it is assigned. It’s less complicated than you might think, consisting of simple math and a few mask nodes.
MF_SphericalPulse animates the radius of two SphereMask nodes. One, slightly smaller, is subtracted from the other to create a hollow sphere. As the sphere expands it will slowly fade out before the cycle begins anew.
This one contains a few hard-coded values because I didn’t want to overload the final Material with parameters. These values plug into the hardness input on the SphereMask nodes, and control the definition of the pulse. At values of 100 and 90 the ring has a hard outer edge with a softer inner falloff.
Keep in mind
Volumetric fog uses a camera-aligned 3D voxel grid with a relatively slow update cycle. This is to save on performance and to avoid jitter and/or other weird real-time behaviour. However, as a result though you may experience strange results if you set your pulse width too thin.
This function is responsible for distorting our spherical pulse and creating the smoke-like effect. There isn’t much to this one, and it’s here that we are finally using our Volume Texture.
This graph outputs a distorted world space position based on a Volume Texture from the engine content called VT_PerlinWorley_Balanced. I chose this one because it’s a texture with three channels so out of the box it’ll distort our coordinates in all three axes.
The function also has parameters to tile and scroll the texture, which I mostly keep to a low value just to offset the texture slightly between pulses so it’s harder to pick out the repeating pattern. You can get some pretty trippy effects by increasing this value.
This is the Material in which we pull it all together. Remember to set your Material Domain to Volume and your Blend Mode to Additive or it won’t work!
You can break the functionality of this Material into two sections. First we use MF_DistortWorldPosition to distort the object’s world position (fancy that), and then we lerp the output by a SphereMask node. This means that the further we get from our object’s origin, the more distorted the coordinates will become.
Next we feed those coordinates into a MF_SphericalPulse node, and plug the result into our Extinction input.
Finally, we add some color. I’ve also added a little bit of optional functionality that will hue shift the pulse’s color. Just for fun.
Volume Materials and Exponential Height Fog
Now that our Material is complete it’s time to drop it into our level and see what happens. I am going to create a simple static cube and apply the Material.
When applying a Volume Material to a mesh be aware that the scale of the mesh will not always dictate the size of the effect. Our pulse radius is defined in the Material, so if you apply it to something much smaller the effect will be cut off. Likewise, if you apply it to a mesh that’s much larger you’ll be doing a lot of unnecessary calculation.
You can use this to your advantage with the strategic placement of volumetric fog-producing meshes. In this cool example, Unreal Evangelist Chris Murphy uses a similar technique to create low-lying fog for spooky ambience.
Before we can see the effect in action we need to add an Exponential Height Fog actor and check the Volumetric Fog box. There are plenty more settings here that can change the appearance of your effect, but I found keeping most of them default gives a good result. If you want to minimize the effect of the height fog but keep your volumetric fog, set the Fog Density value to something small like 0.01.
If you’re noticing that your effect has square-shaped artifacts, that’s because of how volumetric fog is calculated. Its resolution is based on a configurable voxel grid that defines what areas of the level should be affected.
If you want to reduce the size of the cells in this grid (and accept the associated performance hit) you can change it with the following console command: r.VolumetricFog.GridPixelSize followed by the preferred size of your grid in pixels.
That’s it for this tutorial. I hope I’ve given you a glimpse of some of the cool effects that are achievable through the power of Volume Textures. We’ve barely scratched the surface here, so I highly encourage you all to experiment with the Volumetrics plugin and see what else you can create. It comes with a couple of cool Blueprint samples that are well worth checking out.
If you’re keen to learn more about volumetric Materials in Unreal you should also definitely check out Epic’s guide to creating Volumetric Clouds. It follows the same basic principles that we looked at today, but it then takes the concept a whole lot further.
I would love to see what you can come up with using these tools. If you found this post interesting or a useful jumping-off point to create your own effects, please drop me a message and tell me how you did!
Thanks for reading.