logo80lv
Articlesclick_arrow
Research
Talentsclick_arrow
Events
Workshops
Aboutclick_arrow
profile_loginLogIn

Creating Stylized Linear Gradient

This tutorial is to teach you the basics of creating that stylized linear gradient seen in games like DOTA and League of Legends.

Hey everyone! This tutorial is to teach you the basics of creating that stylized linear gradient seen in games like DOTA and League of Legends. We’ll be focusing mostly on learning World Position, Object Position and Object Radius. These three nodes combined will allow us to achieve the effect we need.

In this tutorial I’ll be using a stylized blossom tree created by the awesome Jonathan Riley and has donated it to be used with this tutorial. All files for this tutorial will be available by the download link at the bottom.

So let’s get started!

So, first things first – Let’s talk Absolute World Position. This material editor node gives the exact X, Y, and Z coordinates of your material on an object, relative to world. To demonstrate this, let’s create a basic material, i’m calling mine M_Stylized_MASTER (which will become the basis for all stylized assets we use) and let’s drop in a ‘World Position’ node and plug it into Emissive.

Placing this on our mesh you’ll see a glowing sphere of different colors, each color represents a different Unreal Unit at a given point per axis (X, Y, Z). To make this more visible, let’s place a clamp right after it and plug it into emissive.

By placing this material on any mesh in our scene and moving it around, you’ll find the color of the material changing based on the colors of its position.

So naturally, for our linear gradient we need to grab the Z vector, as we want our gradient to face upward in our material. Let’s add a component mask before the clamp and use B (Z), unchecking R and G. Once we place this on the mesh, drag the mesh around and you’ll find that when the mesh passes below the grid in editor, Z: 0.0, the mesh will turn black.

However, we would like our gradient to stay relative to the mesh itself. This means we’ve got some math to do! This is where Object Position and Object Radius come in. Object Position gives us the value of the center point of the bounds the material is assigned to. We’ll subtract this from our World Position Now you’ll find a hard split of black and white that stays with our mesh when we move it up and down! This will become the basis of our gradient.

Let’s bring Object Radius into the mix. Object Radius gives us a value equal to the overall radius of our object. We will subtract this from our object position, you can think of this as a ‘range’ between bounds and center of the mesh. Again, we want to make sure our math is subtracted from the world position. 

When we do this, you’ll find the mesh is white, this is because we’re not taking into account the height extent we want our gradient to travel up. We can do this by dividing by a scalar value before our component mask. Changing this value extends or decreases the falloff on our gradient. 

 

As an example, I’ve created a material instance and made the scalar value a parameter to show below: 

Alright! So we now have a very cool looking gradient that we can use for our stylized characters and props. But let’s say you want the gradient to begin higher up on the mesh instead of at the bottom? Well we know that the Object Position, that gives us the center of the bounds to our object, subtracting the object radius giving us our radius value for the gradient. We also know that these values give us a Vector 3, or X Y and Z coordinate. So why not offset the Z by adding to it? Let’s give it a shot. To create our new vector, we’ll take a Vector 2 and append on a scalar parameter. This gives us a new vector where X and Y are constant at 0, and the Z is our variable. If we add this to our math to find the gradient, we retain our X and Y, because adding 0 gives you the same value, and adding the Z’s together gives us our offset for where the gradient starts.

And here is an example of it in action!

Now we have a 0-1 gradient value that we can plug into a Linear Interpolate node. This node blends between two inputs based on an alpha, in this case our gradient. For the purposes of the tutorial, rather than using two different albedo textures, I’ve just multiplied one by 0.1 to get a much darker version of the same texture. By plugging the multiplied one into A, and the original into B, we get a gradient between light and dark. Here is an image of the final material. 

Let’s apply this material to our mesh and  see what our results are.

So to make this easier, I’ve turned this into a material function in the included project that you can place in your own materials. To do this, right click and under the alessabaker.net category you’ll find it. Just place that in and plug it into the alpha of a lerp node and you’re good to go! The material function is commented with everything in this tutorial, so have a read over it and experiment! To use the project, extract to the content folder of your project. StylizedLinearGradientTutorial folder should be in the root of your content folder. 

If you have any questions, feel free to email info@alessabaker.net – I’ll be happy to answer. And if you enjoyed this tutorial, I’d appreciate the support by becoming a Patron! Project files will only be available on larger tutorials to Patrons in the future so be sure to check it out!

Alessa Baker, Technical Artist

Join discussion

Comments 1

  • Keller Jackson

    Very cool material function. Super useful! Thanks for sharing. Any idea how to modify this function to work with instanced static meshes (as in the case of foliage)? I've tried plugging the Absolute World Position, Object Position, and Object radius nodes into a vertex interpolator (https://georgehulmblog.wordpress.com/tutorials/get-instance-transform-data-ue4/)  to see if I could get it to work, but I've been unsuccessful.

    0

    Keller Jackson

    ·4 years ago·

You might also like

We need your consent

We use cookies on this website to make your browsing experience better. By using the site you agree to our use of cookies.Learn more