Linear Algebra Part 1

Had a go at learning some linear algebra through a great Khan Academy course today. Vectors seem to turn up in my work constantly and its something I’ve kind of gotten used to through exposure, but I don’t really have a solid grasp on the maths. Hopefully after this course I will!

All images are from the course, which can be found here.

What is a Vector?

A vector is a list of numbers that represents a direction and length in  2D or 3D space.


Vector Addition

Adding two vectors together is like placing the second vector at the end of the first, and then drawing a line between the origin and the end of the second vector.


Scalar Multiplication

When we multiply a vector by a single number, we essentially stretch it out by that amount, or scale it. Therefore in linear algebra numbers tend to be called scalars.



Bases Vectors 

The base vectors are the vectors that all others in our coordinate system are derived from. For example, the most common base vectors are î and ^ j (known as unit vectors) which are 1 in the x and y direction.

Any time we have a vector, it is basically a scaled version of the base vector.


Linear Combination and Span

The linear combination of two vectors is anytime a vector is scaled and added. The span of a set of vectors is all of the possible vectors that can be made using the linear combination. For example, with î and ^ j, the linear combination is made up of all possible 2D vectors, but if we were to use the vectors [1, 0] and [3,0] the linear combination would be all possible vectors on one line. If the vectors were both 0, the only linear combination would be 0.



How Do Normal Maps Work?

As I’ve been practicing normal mapping recently, I wanted to find out a little more about how normal maps for game assets work on a lower level and how they interact with shaders.

Surface Normal Direction

In a standard rgb normal map, each channel corresponds to a surface normal direction.

R = X Surface Normal, G = Y Surface Normal, B = Z Surface Normal

Tangent Space

Tangent space is used to specify coordinates for a poly face. This is mapped in a similar way to a UV coordinate, however the third axis represents the normal of the face, aka the direction that the face “sticks out in”.

X = Tangent (U), Y = Bitangent (V) , Z = Face Normal (N)

R = U, G = V, B = N

The values for these coordinates represent the direction that values increase in across the face.


World Space

The world space explicitly states the normals of an object in relation to the world. Regardless of object orientation, world space normals will always face the same direction in world.

Tangent Bias

Light rays are calculated in world space, whereas normals are calculated in tangent space. So I guess we have a problem here! This is where the tangent bias comes in. This is used to convert from world space to tangent space.

The tangent bias compares incoming light rays against the normal directions in the map, which then determines how each pixel is lit.

There are many different way to calculate tangent bias. It is important to match these between baking and shading applications, in order to get correct results.

Some engines may skip tangent bias calculation, instead opting to convert the tangent space normal from the map into world space within the shader, before comparing against light rays.



Unpacking Normals

When saving a normal map out from a baking or painting application, it is limited to a positive range per channel, e.g 0 – 255. When this is used in a shader, it is parsed as 0-1. However, being directional coords, normals need to use negative values, so we “unpack it”, remapping it into -1 – 1. This gives us access to all channels, including alpha, as well as the normal vector length.

Why Are Normal Maps Blue?

The 0, 0, 1  colour created on bake represents a flat surface in a normal map, with the blue value representing a completely outward facing normal direction. When this is remapped into 0 – 255 to become a texture map, it becomes 128, 128, 255, giving us a purpley blue colour.