UV Scaling & Offset

From Shader Forge Wiki
Jump to: navigation, search

UV coordinates overview

Let's say you have a basic diffuse shader with a single texture like so:

DiffuseExample-no-UV.png

What SF does in the background without telling you, is it automatically adds some default UV-coordinates for the Texture sampling to use. UV-coordinates are used for determining which pixel from the texture being used is shown at any given points on the surface of the model. UV-coordinates are a two-component vector with values ranging from 0 to 1. If you were to visualize what these UV-coordinates look like, you'd get an image with a red and green gradient, the former for values on the horizontal axis, and the latter for the vertical axis. Fact is, we have a node for this:

DiffuseExample-UV.png

If you hook a UV Coordinates node to the UV input on your Texture2D node, you get the same result as you did without the node, this is basically what ShaderForge does in the background when you don't hook anything into the UV input. Now however, we have control so we can run some experiments! Just like anything else, you can manipulate the UV coordinates. Like I mentioned previously, default UV-coordinates are two gradients, from left to right and bottom to top respectively, with values starting from 0 and reaching 1. Every combination of values on this two-component gradient correspond to a specific pixel on a texture. If you instead of these gradients gave a single Vector 2 to the UV input, you would display only one of the pixels in the texture for the entire surface, like so:

Diffuse-Single-value-UV.png

As you can see, the sphere now displays a single beige color instead of the brick-texture from before. What is happening is that it's actually displaying a single pixel from the same brick-texture. Since the Vector 2 node has the values 1, 1, it will display the most top-right pixel in the texture, which happens to be this color. Trust me, it's still the same texture.

This alone isn't very useful currently, what this control over the UV-coordinates is more commonly used for is Scaling & Offset (as the title of the page implies).


Scaling

Scaling the UV coordinates will result in the pattern of your texture to repeat more or less often than it does by default. You could also call it 'making the texture smaller or larger'. Scaling is done via multiplying the output of the UV coordinate node with a value, like this:

Diffuse-UV-scaled.png

As you can hopefully see from the screenshot, the bricks have become smaller, because a higher multiplier will make the texture repeat more often! You can also multiply by a Vector 2 if you want to scale the vertical and horizontal axis independently from each-other, like so:

Diffuse-stretched-UV.png

Doing this will generally create a stretched look which might not fit all textures, so be wary. In this case the horizontal axis is repeated less often which makes it look wider, while the vertical xis is repeated more often making it look flatter.


Offsetting

Offsetting the UV coordinates will instead make the position of the texture appear to line up differently. Scaling was done by multiplication, offsetting however is done by addition (or subtraction for that matter), like thus:

Diffuse-UV-offset.png

I'm using a plane-mesh instead of the default sphere to better illustrate the effect, you might notice how the texture doesn't line up with the edges of the model because it has been shifted slightly on both axis. Negative values in this case simply offset in the opposite direction.


A little trick

Now, you might have realized that doing these operations is kind of unnecessary, since this is exactly what already happens when you type in values for Tiling & Offset in the Material inspector, Unity already provides you with this control outside of ShaderForge. It is nonetheless essential knowledge to be able to do more advanced UV coordinate related tricks later on. I'd still like to finish off with an effect using only what we've learned here. Look at this screenshot:

Beachball-UV-trick.png

What you have here is manipulation of UV coordinates to create a blurry striped effect, which when applied to the standard sphere mesh, could perhaps be interpreted as a beachball, or if applied to a plane and made to have Additive blending, a forcefield effect!

We are using the U component of the UV coordinate node alone, in order to read a row of pixels, which we also scale down to get this blurred thick-lines effect. Then we have a new cool node called Append, which essentially puts two components together to build a Vector 2, which can be used as input for UV since it expects 2 components. The value of 0.4 is basicly used for selecting where the row of pixels is read from, in this case a bit below the mid-height of the texture (0.5 would be the middle). As you might remember from the top of this article, issuing something other than a gradient to UV will result in reading the same value from the texture every time, in this case the same row of pixels from the texture for the whole mesh, so it will look like vertical bars. There's an extra Texture2D node called Reference, which shows you the texture I used for the effect, it's a texture included in ShaderForge called MotionBlurJitter.

Shaders are cool, aren't they? Catch further UV coordinate reading over here at UV Rotation & Panning.