Circled-shaped HP bar with alpha mask

Hi there.
I’m attempting to create circle style bar and I thought using an angle alpha mask would be the way to go performance wise, but I just can’t manage to control it properly.
This is the mask I’ve been trying to use and the bar I’ve been trying to mask.


This is what I’ve attempted to do, but I just can’t control it by using a variable or anything.

I tried multiplying the mask and then flooring the values to get a one bit alpha mask, but it doesn’t work the way I want it to. I just want to be able to control how much of the bar is shown with a percentage. Like if I say “display 75%” then it displays 3/4 of the circle and so on.
Can anyone enlighten me with maths goodness? :slight_smile:

The material function vectortoradialvalue can actually generate that radial mask using UVs. I will load up the editor in a few hours and see what output you need to use.

As far as getting your texture version to work, is the gradient linear? If so go into the texture options and make sure you uncheck sRGB. That will make it linear, since sRGB makes things nonlinear. A more stable way to control the distance would be to add instead of multiply before flooring. Adding 0 would be 0%, 0.5 would be 50% etc.

Well, using Add instead of Multiply kinda works, however I get these really bad jaggies:

Also, the values are still a bit off. Using 0.75 didn’t really get me a 3/4 of the circle, it’s a little bit less than what it should be. I guess I can fix that by giving it an offset, but I think the radial mask you’re talking about is the way to go.
My mask also has sRGB unticked, so that shouldn’t be the problem. When I choose TC_Grayscale the gradient gets really smooth, but then I can’t use it in my material.

That edging is probably due to the DXT compression. You CAN use grayscale, you just need to change the Texture Sampler type to ‘Grayscale’ instead of ‘Color’. (Still don’t fully understand why that limitation is there, it’s a pain for swapping out textures in Material Instances).

Thank you. That actually got rid of the edging. However I’m still having trouble with controlling it properly.
Maybe my alpha mask is wrong somehow? Here, I’ll share it.

Also, you can see here what happens when I add “10” and “50” percent.

^This is by no means a 10% of the whole circle. That’s a lot more.

However, 50% is almost spot-on.

Looks like its one of the photoshop gradients. I am pretty sure those aren’t going to be radially linear. Look into the vectortoradialdistance function, it has an output exactly like that that is computed using atan2.

To replace your texture, do this:

Place the function “VectorToRadialValue”

For the first input labelled “Vector or UVs (V2)” input a TextureCoordinate node that has 0.5 subtracted and multiplied by 2 (or you could use the constantbiasscale node with bias -0.5 scale 2). Then use the output “Vector Conveted to Angle”. Then the add, floor thing works exactly the same.

If you want to flip the gradient on any axis, change the constant 2.0 to a V2, as in -2,2 or 2,-2.

That will give you a perfect gradient. In your image in the last post, the 10% actually wasn’t too far off. 25% is a full 90 degrees. Looks like it was reading the 0.1 as around 15% or so.

You could even replace the outer circle texture very easily using a variety of techniques. You could use spheremask twice, once inverted (1-x) to control the sharpness or use the floor node if you wanted it perfectly sharp.

Thank you. That worked wonderfully.
Is it also possible to use this same node to place another texture sample to a certain angle? For example, adding a “cap” at the end of the bar depending on the percentage you indicate.


Is it possible to adjust the VectorToRadialValue output so the black|white threshold is at 12 o’clock instead of 3 o’clock?

I need an extra -90deg (-1.571 radian) offset so the start/end of the angle gradient is at the top.


That is pretty easy. You just need to rotate the UVs by 90 degrees going in. You should be able to simply use the Swizzle material function. Plug the UV node into “XY” and then use “YX”. If that ends up facing south instead, you could do component mask and use 1-x on the Y component and then re-append.

I actually did something similar to this for my radial bars, which start at various weird angles like 14° from the top and variously fill clockwise or counterclockwise, by just making modifications to the VectorToRadial function itself. This lets you control the atan2 function that generates the gradient in a much more detailed way (by adding a “+[constant]” to the math expression itself, IIRC?)

The only caveat is to make a DUPLICATE of the default function and to place in your game’s folder rather than the engine folder, otherwise updating UE will break the function modifications you’ve made

>That is pretty easy.

It was indeed :slight_smile:
Thanks for the explanation Ryan!

>The only caveat is to make a DUPLICATE of the default function and to place in your
>game’s folder rather than the engine folder, otherwise updating UE will break the function modifications you’ve made.

You are correct RhythmScript so (for me at least) Ryan’s solution was the best way to go.
The Swizzle material node solved the problem instantly.

Nonetheless, your tip is valid as there are interesting values inside VectorToRadialValue that I may want to inspect later.

Guys what if I want to create only a 180 degrees clipping mask? yours tutorial show only 360 degrees technique. Please Help!!

Oh common think a bit. All you need to do is feed parameter that rotates from 180 to 360, that is easiest solution.

not to derail this in a new direction but what about using UMG’s dynamic materials option?

As someone who HAS hacked around inside VectorToRadial (to change the initial location of the gradient’s start around the circle), remember to first DUPLICATE THE FUNCTION, AND MOVE IT TO YOUR PROJECT FOLDER, and then modify the duplicate. Changes made to the UE4 internal one will be overwritten whenever you update to a new version of the engine and it will break whatever tweaks you’ve made.

Hi there ash22,

I was trying to do the same thing, so that the sweep started at 12 o’clock and went around clockwise.

I ended up creating my own custom material function but copying half the VectorToRadialValue function. However, I adjusted some of the math at the beginning so that it produced the results I wanted.

Note that the TexCoord values are -2 and -2, and the scalar being subtracted from it is -1.

I have also swapped the mask G and R around into the x and y inputs to the atan2 node.

The atan2 node is a custom node, and the code is return (atan2(y,x)); with an output type of CMOT Float 1 and 2 inputs, named x and y.

Enjoy :slight_smile:

Hello KeytoTruth (And all others) :slight_smile:

I ran across this thread a few hours ago and thought I would make a Dynamic Radial System for you (which you are free to use or modify in any way for any project). Below are all the files (Requires 4.6). I hope you find it useful.

This (meaning: the Masks and Circular Objects) are generated from pure math (No textures). This means all parameters may be tweaked without fear of quality loss.

  • The only texture is a simple noise which is used as an overlay for Polar Coordinate based animation -

Some of the features:

  • Start the animation from any degree
  • Dynamic Endpoint
  • Dynamic Polar Coord. Animation
  • Full Color Based on Vector Grads
  • And much more!



Here is a video to demonstrate the shader.

Hello! Thank you for your efford. Could you however make a tutorial about how to create the bar from a scratch using your already build assets? It would help much to undestrand how to use assets created by others and to how to use materials! It would be very very helpful. Thank you.

I copied the folder in my project but i havent got any clue how to use it in project.