All example project files for this and future tutorials can be found here

Please download and follow along with the examples and experiment - always the best way to learn!

Toady we're going to be looking at UV's and what they actually mean in terms of Math and how we can play with them for our benefit!


Firstly I've just plugged the UV output into the emissive node and we get Reds, Yellows and Greens.  What's going on?  Well if we use our Mask node and break out the channels we can see it's actually just a black to white gradient in the red and green channels and blue doesn't exist. - UV's are a Vector 2.  

Basically what we have here is a lookup table - each of the pixels in the layout is uniquely identified by it's red and green component and that tells the engine what pixel to refer to from the texture the UV layout is plugged into.  

Here we're just using the UV node as most of you will already know how - plugging it into a Texture Sample.  Unreal automatically assumes default UV values if this node isn't connected so you may never have needed to connect like this before.  

Notice here that we've used a Texture Sample, and masked it to a Vector2, instead of a UV layout.  It's just two gradients I've created in Photoshop but we're getting a really noisey result - so what gives?  Basically compression is the issue here - Textures in Unreal are compressed to save memory but UV's are very sensitive to change so we're seeing those compression artifacts.  Note if you just want a gradient it's cheaper and more accurate to mask a UV sample rather than importing a texture, you might remember I used this technique in the Math examples.

These next three nodes are just showing how Tiling works - All the UV nodes are setup with a Tiling of 4,4.  Notice when the first Node is connected you're seeing a lot of blooming Yellow, this might remind you of something from the Math example - Unreal is trying to display numbers over 1, so if we Frac it down we can see the gradient is repeating over the layout.  Note the whole number part of a UV layout is totally ignored, only the fractional part is relevant.  This is the reason that textures tile.  

Note there's no reason that a texture has to tile uniformly - here I've set up a tiling of 1,0.1 so only the first column of the texture is visible.  This can be useful for things like packing multiple textures into one sheet or for creating a long texture and then un-stretching it in the material so only a fraction is visible at a time.  

So now we know that UV's are just Mathematical gradients, what happens when we start adding numbers to them.  Well, as you might have guessed, they move!  Adding numbers to R moves things horizontally, G vertically.  So what happens if we add a changing value, such as Time - a scrolling texture! and how about if we just want to scroll in a single axis?  Simple, just add the Time to a single channel.  

So what we've created here is what Unreal refers to as a Panner node - but it's basically doing the same thing, just moving the UV's over time by adding values to the U and V channel.  Notice that if we plug a constant value into the Time input of the Panner we get control over the movement without any scrolling, useful to directly control your material offsets.  

Similar to the Panner is the Rotator.  This is doing much more complex math but basically it's doing the same thing, just changing the input UV values mathematically to create a rotation motion.  

So now we're getting to some interesting things - what happens if we scroll a texture and add it to our UV layout.  Well with this kind of mask we get a strange bulging effect, very cool.  Note we've had to scale the texture right down, UV's are very sensitive remember.  This is super useful and the basis for all sorts of VFX work - water, fire, cloth etc. 

Here's another example where we're just adding a simple noise texture to our UV's - it almost looks like we're looking at the texture through a water surface.  Note the White values on the right hand side of the image - here the texture has wrapped around from the left.  Because we're adding values in both axis the noise is going to move things up and right - maybe not a problem if we're dealing with a tiling texture but if we do want to keep things centred that's easy enough - just subtract 0.5 from out input noise before we multiply and add - now our texture range goes from 0 - 1 to -0.5 - 0.5 so the noise equally adds and subtracts from the UV's and keep the image centred.  

Here we've just plugged a Time Sine into our Panner to create an oscillating texture, but we're not getting a tiling effect of the black and white repeating like we'd expect.  So what gives?  Here the trick is in the texture - if you double click it and open it's settings and click the drop down to extend the Texture section there are options for X and Y-Axis Tiling Methods.  In this case we've set this to Clamp so rather than Tiling the Texture the Engine just repeats the last pixel, which in our case is pure black or pure white - creating this sliding door effect.  Super useful.  

A bit less useful but included for the sake of completeness - there's also an option to Mirror UV's instead of Tile or Clamp.  Here we've created a circle but if we inspect the texture we can see it's actually just a quarter of a circle.  Could be useful in certain circumstances.  

Here we're plugging a texture, masked to a Vec2, into our fake UV layout from earlier - so what's happening.  Well if you remember the Black and White values of a UV layout are just a lookup table.  So here the Black and White Vec2 mask we're using is just being remapped to the colours of the second texture - exactly like the Gradient feature works in Photoshop.  This is super useful for things like Fire where we can use lots of different black and white masks to create our shape and motion and then use the same gradient on all our fires to ensure a consistent colour and allow for quick and easy editing.  

Lastly you've probably noticed the TexCoord[0] in the Name of the Node. Well TexCoord is just Unreals name for UV and is a shortened version of Texture Coordinate.  The [0] refers to UV layout 0 - it's really useful to unwrap a model in multiple ways and keep them all in the model for different uses - for example a Character might have a large tiling unwrap for things like cloth detail normals and then another unwrap that is just a front Planar projection which allows for a quick way to paint mud kickup on the bottom of the trouser leg etc.