So, a quick forward before we get into the nitty gritty of this topic.

I love making stuff look cool.

I also love helping others out, and, as my area of expertise is very much in the Unreal Engine, I’d be out of place if I didn’t say I love helping out fellow devs. The UE community is one for giving back, and, in light of my recent foray into demonstrating some of my work, I’d like to give a little back.

Today I’ll be talking you through Isolated Shader Opacity. For the laymen, that’s the same technique I used in my Seasonal Environment to make the leaves disappear during the winter.

Basically, we’re going to make a shader, and, in part 2, an accompanying blueprint setup to control that shader.

In the image below, you can see that when a particular variable is set to 0.5, the image is HALF WAY visible, in a location that we decide through an image. Because of the nature of this kind of work, 0 doesn’t ALWAYS mean invisible, and 1 doesn’t ALWAYS mean completely visible, BARE THAT IN MIND. It would be a fine world if there was a 1-shader-fits-all approach, but sadly, there isn’t. Occasionally, we have to go above 1 or below 0 to get the look we’re after. However, we’re competent Tech Artists and can handle this, no biggie, no harm no foul.

My example needed to have a value of about -0.1 to turn invisible.

By the end of this short tutorial, we should end up with this –

With that being said, lets clear up a few things.

Firstly, I need to make something abundantly clear – a texture sample, no matter what anyone else might tell you, is made of numbers. If its in the unreal engine, its most likely a 8-bit, 16-bit, 24-bit or 32-bit collection of numbers. That RGB you’re always seeing? That’s a 24-bit number, 8 bits to store red, 8 bits to store green and 8 bits to store blue. You might even have seen the odd RGBA image type around – that’d be your 32-bit image right there.

In addition, we need to know the difference between Float2, Float3, Float4 and Float1 values. Its pretty simple –

Basically, take the number after the word float, and we can fill in the blanks from there.

1 – A single number, like the value we’ll be using above.

2 – Two numbers, for things like UV Coords.

3 – Three numbers, for things like colours and regular images

4 – Four numbers, for when we need an image with an extra 8 bit stuck on the end for more advanced material stuff. Especially useful for when you have a texturesample limit and want to squash more information into a smaller space…its a bit advanced, so if you’re not totally comfortable with Float4’s, don’t worry about it.

You might see your 24 and 32-bit images referred to, especially in UE, as Float3 and Float4 values – this will come into play later on.

Have you ever wondered what those dots were next to a texture sample? Those are access to specific sets of bits WITHIN that 24 or 32.

There’s also another important thing to take into account – WHITE and BLACK, in the eyes of the renderer, is just 0 to 1. I cannot stress this enough. This concept is going to be VITAL later on, so stash it in your brainbox.

As technical artists, we use this numeric information to manipulate and change appearances to create interesting aesthetics.

With that out of the way, let’s get to make some lovely technical art.

Step 1 – Assemble your maps

These can be made in any art program, really, but I used Photoshop CS6.

To make the above piece, we’ll need, at its simplest;

A gradient map, prefixed with GRAD_

An opacity mask, prefixed with MASK_

On the left, our Opacity Mask. White will be visible, Black will be masked. On the right, our gradient mask – this can be practically anything

It might be an abstract concept, but we can look at a Gradient Map as visible time – our shader will find the lightest pixels first, and consider them to be made invisble FIRST. As we make our threshold larger and larger, the shader will consider more and more pixels for invisiblity. Eventually, the entire thing will be see through. Confusing, I know, but everything’ll turn out find at the end…promise.

I personally use .tga (TARGA) files for textures, mainly because the compression on them is pretty fantastic, they stream well and are capable of handling 24 and 32 bits worth of colour information really well. If you, for whatever reason, cant save your image out as .tga, then .png is perfectly fine, no harm done.

Now we’ve got our textures and whatnot done, lets move into UE4 and make some fancy pants shader stuff. Well, its not that fancy pants, but useful none the less. Import your two maps into UE4, and lets get started.

Step 2 – Establish your infrastructure to handle future scripting

In your content browser, we’re going to need a Material Parameter Collection (MPC_). Inside that, we’re going to need a Scalar Parameter with a suitable name; I made one called MPC_TutorialValues, with a Scalar Parameter called MaterialAlpha.

Along with a Material Parameter Collection, we’ll want a Material to stick on whatever asset we feel like.

BUT TOM, I HEAR YOU CRY, WHY NOT USE MATERIALINSTANCES!?

Well, curious and rebellious artist, i’ll tell you why.

Material Instances are all good – don’t get me wrong. However, Blueprints cannot TALK to them. If we had some way of communicating and messing with the parametric values inside of a material instance, then it’d be all well and good. Alas, we cannot.

However, a Material Parameter Collection, as you might expect, CAN talk to blueprints. Moreover, we can reference them REALLY easily! More on this in Part 2, though (its really easy, i promise).

Step 3 – where the Material Magic happens, where all of our lovely numbers come into play

So, right now, you SHOULD have in your content browser 2 textures (one Gradient mask and one Opacity Mask), a Material Parameter Collection with a single Scalar Parameter in it, and one Material ready to receive some love.

First and foremost, open up your material – this UI should be pretty familiar (if not, this probably isn’t the tutorial for you).

Set your blending mode to Masked – this allows the renderer to use our Opacity Mask as an input.

Drag your Material Parameter Collection from your content browser INTO your Material Editor. You should get this bad boy-

Click on it – on the left hand side, we’ll see a number of options, including a drop down box marked Parameter Name. If you open up the drop down, we’ll see the Scalar Parameter we defined earlier.

After selecting the parameter we want to use, our setup should look like this –

With this parameter in place, we can use it to control ALL SORTS of animated materials. This is basically our link between Programming and Materials. Coming back to what we discussed earlier in regards to an image simply being a collection of numbers – note how the decription under the “MPC_TutorialValues” has changed from (float4) Collection Param to (Float1) Collection Param. This means the node is outputting a Scalar value, which is exactly what we want (scroll back up and check out the section on different types of float if you need to). Now, lets use it to do some maths.

Here is the final material setup. It might be a good idea to copy it first and read on for explanations as to WHY it works.

You can test this setup by playing with the value stored in your Material Parameter Collection – it’ll update your shader in realtime.

Hopefully, you’ll have a dynamically animated shader! The scribble should fill up from the bottom to the top.

Step 4 – Why on earth this works

The real star of the show is the IF node.

Essentially we are comparing our fed parameter from the Material Parameter collection to every pixel of our gradient map. As I mentioned earlier, a white to black image is simply a transition from 0 to 1; this is why we only have to change out Material Parameter Collection’s Scalar Value from 1 to 0 to get such a drastic change in appearance.

If a pixel is greater or equal to the value of our Scalar Parameter, then we output a 1 for that PIXEL; conversely, if its anything else, we’ll say its 0. We can see this in action in the real time viewer of the If Node itself – that black band across the bottom is the section of pixels that fall into that particular threshold. As we increase that threshold, more and more pixels qualify, and the band gets bigger.

Moving on from there, we have the subtract and the clamp.

Any pixels that are black have a value of 0. Therefore, if we subtract ANY value from them, then apply the clamp, they remain at 0, they remain unaffected. Any pixels that are white have a value of 1, and, as such, we are liable, and ABLE, to subtract value FROM them. From that white area, we’re subtracting whatever the IF node deems appropriate, hence changing what gets masked.

Step 5 – Take a step back, you’ve just changed how you see digital art

For me, this was the breaking of the 4th wall. Pictures are NOT just pictures, they’re a beautiful collection of floats and bits, nothing more. Images? Pff, they’re just numbers and mathematics tricking you.

This concept is MASSIVE. Master this, and you’re golden, you’re well on your way to making custom health bars without having to rely on UMG’s awful progress bars (im so sorry Epic, i love you). And bare in mind, the gradient mask doesn’t have to be a linear one like mine – it can be ANYTHING as long as its greyscale, a fancy pattern is just as good.

I really hope this tutorial helps you guys, and have fun!

As always, if you’ve any questions or just want to message me, you can always get in touch with me @tomshinton on twitter, or through the other means on my Contact page to the left.