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!

Today we're going to be looking at some of the Vectors that Unreal makes available to us in the Material editor and how they might be useful in our shaders.  

Note that so far we've been using Vectors mostly as colours, but there's a couple of super useful Vector3s - Position and Direction.  In each case the XYZ either describes a coordinate (such as 0,0,0 being the Origin of the world) or a direction Unit Vector (a unit vector just means that the length of the vector is 1) such as 1,0,0 pointing directly along the X axis.  

Because we're going to be previewing positions and directions via colour some of the previews might not be that helpful but, as always, take the time to apply the test material to a mesh and move it around the level to see how things are working. 

Camera Vector

This isn't the most useful vector but hopefully displays some of the key concepts I've mentioned above.  Basically this node outputs the current direction of the Camera as a Unit vector.  Notice how the object changes colours as the camera orbits around and points in different directions.  Often with vectors it's only one channel we're interested in so here I've masked off the R channel, and Abs to ensure positive values - notice how the object goes completely White when the camera is aligned with the X axis.

Reflection Vector

This node outputs a direction vector that represents the Camera direction reflected across the surface normal.  Basically if we fired an imaginary line from the camera how would it bounce off the surface.  If we mask off the RG channels what does it remind you of?  If you said UV layout you'd be correct! - If we plug this node into a Texture Sample we get some pretty convincing reflections (the texture is just one I captured from the Particle Cave example map). 

Up Vector

Here we've manually specified a 0,0,1 Vector and we want to use it as a vertical Direction Vector rather than the colour blue.  By default everything that plugs into the Material pins should be in World Space so by Transforming the Vector from Tangent to World we get the up vector mapped over the surface.  If we just mask out the blue channel hopefully we can see why this would be useful - it creates a mask that always points up regardless of the objects orientation - really useful for things like snow deposit or moss shaders.  

A quick aside on Spaces - World Space is just the basic Unreal grid, with 0,0,0 in the centre and the X,Y,Z axis aligned with Up, Left/Right and Forwards/Backwards.  Local Space is unique to each object - 0,0,0 is the origin of the mesh and X,Y,Z are aligned to the mesh as it was exported from the 3D modelling package.  Tangent Space is related to the surface with 0,0,1 being the Normal direction, directly off the surface at 90 degrees to the face. 

Pixel and Vertex Normals

Firstly here we need to make sure that the material is using the Default Lit shading model and then connect the Normal Map to the Normal pin.  Now when we connect the PixelNormalWS the Normal map is taken into account and each pixels normal direction is displayed.  Compared that to the VertexNormalWS node - we're still seeing some shading from the Normal map but the Vertex normal isn't being affected.  Note the WS just stands for World Space and is a helpful reminder what space the data is in.  

Another quick aside on rendering - the way the engine draws meshes is a two step process: the Vertex Shader and the Pixel Shader (also sometimes referred to as the Fragment Shader).  Firstly the engine takes all the Vertex positions and creates a triangulated mesh using those positions, then it fills those triangles in with Pixels.  This example, hopefully, illustrates that in action - the Normal map is affecting the Pixel shader but the Vertex normals remain unaffected.  


So now we know a bit about some vectors lets use on in a slightly more practical example.  Here we're using a Dot to do a comparison between the Camera Vector and 0,0,1, Transformed to Tangent space.  It sounds complicated but hopefully from the preview we can see what's happening:  The 0,0,1 Transformed to local is just the surface normal, and when we Dot two vectors we're basically doing a comparison - we get White when they're aligned and Black when they're perpendicular, so in this case we're getting a Fresnel effect (named after a French mathematician and pronounced Frenell).  Helpfully Unreal has provided two Fresnel nodes which have this same functionality, one simple and one complex.  

How do things change if we do our Dot between the Camera and the Pixel or Vertex Normals instead?  What about if we have the Normal map plugged in too?  Maybe we could even plug the Normal map into the Transform Node?  Try all the different combinations and see what effects they have.  

Absolute World Position

So far we've mostly been looking at Direction Vectors so lets take a look at a position Vector:  Absolute World Position.  The first thing you'll notice if you plug the World Position directly into Emissive is the massive bloom - Position Vectors are outputted in World Space units so the numbers get very high very quickly - if we Clamp it down we can start to see what's happening, or better yet just divide by a large number to get useful ranges.  Here the World Position coordinate of each pixel is being output - if we mask off just the G channel hopefully we can see this a bit easier.  Note you might need to move the object around in the world to see this effect clearer.  

Underneath we have Object Position - this Node is very similar but outputs a single Positional value, based on the objects origin, rather than different values per pixel.  

Procedural Texturing

So now we understand our Position Nodes lets use them in a couple of practical examples - Firstly we're taking the Object position and plugging it into the Time input of a Panner Node - Now when we move the object around in the Y axis (because we've just masked off the G channel) the texture scrolls around the object.  This is a great technique for adding positional variation to materials - you could for example take a dirt overlay map and use this technique so that if you had multiple copies of the same mesh next to each other, each would appear to be be slightly different due to having different offsets on the Dirt map.  Note this can only be used on static objects - if things are moving then this effect would break, unless that's the effect you're after (rotating wheels on a background object car for example could be done cheaply with a shader like this etc.) 

Secondly we have something similar but sort of opposite - here we're taking the RG channels of the World Position and plugging them into the UV's of a Texture - basically what we're doing is a projection mapping from the top down direction.  This kind of technique is really useful for things like Terrain or Water where we know the surface will always be facing up and allows us to use different size and shape meshes and ensure that they always Tile correctly and don't create seams etc.  Similarly if we wanted to create scrolling raindrops on a variety of surfaces this would be better done mapped to World Space so the UV's and scale of the meshes didn't matter.  Again this only really works if the Mesh is static, although you could do something like mapping a smoke Texture to World Space and then apply that to a flashlight light shaft - then when the player moves the light it will look like the smoke is in the world.