This is the second part of an ongoing tutorial series on creating a Halo-inspired Bubble Shield for Unreal Engine 5. You can find the other available parts of the series here.
The internet doesn’t really have a shortage of material-based VFX tutorials on creating force field effects. Nonetheless it’s a rite of passage for every tech artist, and this one is mine.
This tutorial will take you through the process of creating a refractive force field material using Unreal Engine 5. Using the assets we created in the previous part of this series, we will be breaking down the intent behind each creative decision as we go.
It’s my intention that this article is able to stand alone as a how-to guide on fulfilling all of your Unreal Engine material-based force field requirements. As such we will be starting from scratch and working our way through.
That said, this is the second part of a series so several of the things we create today will use existing assets, and be geared towards future features that are beyond the scope of the article itself. I’ll try to be clear whenever this occurs.
For those who are confident in their skills with the Material Editor and just want to see the complete graph as a reference or jumping-off point, here you are. Thanks for dropping by!
If you would like the source files from this tutorial, I would like to invite you to subscribe to my Patreon, where you will be able to download them alongside the source files for all current and future techarthub tutorials.
To get started, you’ll need an existing Unreal Engine 5 project.
If you’re planning on following along with me as we add functionality to our Bubble Shield in future parts of this series, I highly recommend creating a new project based on the Blueprint First Person template with Starter Content disabled. We’ll be using assets from this template to create some functionality further down the line.
Once you’ve got your project up and running you’ll need to import the source assets we created in Part 1. This includes importing your Hexagonal Sphere as a static mesh, and any texture(s) you intend to apply to it.
Before we jump into the Material Editor I’m going to drag my static mesh into a simple test map I’ve created and apply a newly created Material I’ve called M_Bubble.
I’ll be using this environment to demo our Material’s features as we go. You might want to consider creating your own, because it’s far easier to play around with refraction when your environment actually has something to refract. You can find the Color Calibrator mesh I’m using here in the Engine Content under Engine/EditorMeshes/ColorCalibrator.
Creating the Material
Opening up our M_Bubble material, the first thing we’re going to do is set our Shading Model to Unlit, and tick the Two Sided checkbox.
Setting our Shading Model to Unlit will mean our Material won’t be affected by lighting, so it won’t receive shadows and will look the same in full sunlight or pitch darkness. This step is optional, but it really sells that future energy vibe if the shield is self-lit.
It’s also a lot cheaper on performance, which is good because we have big plans for this asset.
Let’s give our Bubble Shield some color. As we’re using an unlit Material, we’ll be plugging our color information into the Emissive channel.
This part of the graph is relatively simple, but will become the foundation upon which we’ll layer on more features. It is made up of two sections.
The Fresnel section is where we generate a customizable Fresnel effect, and then multiply it by a TwoSidedSign constant so that only the outer shell of our shield is affected. This effect of this node will become more obvious in the next step when we set our material to be transparent.
By default, the Fresnel node will use the Pixel World Normal as an input, which means it will be affected by per-pixel effects like a normal map. I’ve chosen to instead use my mesh’s Vertex Normal to emphasize the hexagonal shapes present in the geometry.
You’ll get drastically different results if you use hard-edged or smoothed vertex normals. For this tutorial I’ll be using hard-edged normal information because it’s objectively more cool. You be the judge!
The Emissive Color section will then use the output of the Fresnel to lerp between two colors, a fill and edge tint. I’ve bumped up the latter of these values to a value of 32 to make it glow. Depending on your project’s post processing settings, you may need to push this higher to get the same effect.
Go back into the Details Panel, and set your Material’s Blend Mode to Translucent. Don’t worry if it looks a little ugly at first. Two-sided transparency often needs a little finessing to look the part.
Our Force Field Material’s opacity chain will add two new sections to our graph, and borrow from an existing one.
The Depth fade section uses a few new nodes:
- CameraDepthFade is an inbuilt Material Function that outputs a value from 0 to 1 based on the camera’s distance from the surface of the object.
Depth Fade also outputs a value from 0 to 1, this time based on the distance between the surface of the object and whatever is behind it.
Combined, these two nodes will allow us to reduce ugly intersections by softly fading out the Material as it intersects with opaque geometry (like the floor), and avoid visual popping as the camera moves through its surface.
The Opacity section is small, and just plugs everything together. We use the Fresnel section to interpolate between a minimum and maximum opacity value (so the edges of the mesh’s exterior are more opaque, and the effect is more subtle within the sphere), and then we multiple the result by our Depth Fade section.
You’ll notice we lost a lot of that lovely red glow when we switched modes to Translucent. This is normal and expected, but not ideal. When we add some functionality to our Bubble Shield in future parts of this series, we’ll loop back around and add some light to address this. It’s just not a problem we can solve from the Material Editor.
Now we’re getting into the interesting stuff. The refraction part of the Force Field Material has a little more going on.
Unreal (and many other game engines, for what it’s worth) has trouble with self-translucency, which is when you can see an object through itself. This is simply a weakness of the method by which Unreal sorts out which geometry should be drawn first when it renders a frame.
It’s a very old problem that we’re not going to solve today, but it does rear its head when we try to get discernable refraction on both the outer and inner sides of our Bubble Shield without it looking like a hot mess.
What we want to do is make sure that if we’re on the outside of the shield and looking in, the refraction on the inner surface of the shield doesn’t contribute too much to the effect. This way the outer hexagon pattern can still be made out, and whoever is inside the shield will be discernible.
Here is how we do that.
This whole first section of the graph is dedicated to figuring out where we are in relation to the surface of the shield. These nodes are calculating the distance from the camera to the nearest point on the surface of the shield, and since we can also calculate the radius of the sphere using the ObjectLocalBounds Material Function, we can use that information to tell whether or not the camera is inside or outside of the sphere.
By clamping this value and then using it to blend between two scalar parameters, we can ensure that no matter which side of the shield we’re on, the refraction on that side of the shield will present properly and the other side will drop into the background. As we move through the shield, the values will softly blend to get the best result from any position.
The effect of the refraction with this effect disabled.
With the inner refraction dropped back.
The rest of the refraction part of the Material is pretty straight forward, we add in an Outer refraction value, and we lerp the whole thing by the mask texture we created in Part 1.
Finally, we grab the end of our opacity chain, pass it through a one minus node (because for refraction, a value of 1.0 means no refraction at all), and use that as the alpha in one final lerp. We do this just so the refraction will also fade out like the rest of the material when it intersects another mesh or when the camera passes through it.
Adding a normal map isn’t strictly necessary for the effect, but I think it’s worth adding. Using the texture we created earlier in Part 1, there isn’t much to it.
All we’re doing here is using a Normal strength value to lerp between our texture and a value of 0,0,1. This works identically to the FlattenNormal function you might already be familiar with, except it’s inverted because that makes more sense. At least in my opinion.
We’re almost done, just one last crucial step to go. We need to label and categorize our parameters. There aren’t many so it won’t take long, but it’s always important to make sure your work is legible before you move on to something else.
Even if you’re not working as part of a larger team, you may come back to this material in a few months (if you’re following along, that might be because it takes me ages to make each one of these) and realize you no idea what you were doing.
That’s a wrap for this tutorial. Thanks a lot for reading, I hope it’s been of use!
Remember, you can find all of the available parts of this tutorial series here, and I hope you’ll drop by again for the next one where we’ll be exploring some really interesting volumetric effects for our Bubble Shield’s interior. I’m very excited to share it with you.
Until then, good luck with your projects!