Unity: How to Normalize a Vector

May 16, 2023

Overview

Vectors play a fundamental role in various fields. These fields include mathematics, physics, computer science, and game development. A vector represents both magnitude (or size) and direction.

Normalization is a standard operation. This operation allows us to compare the direction of two vectors. In this article, you will learn what vector normalization is. You will learn why normalizing a vector is important. And, you will get to see some different methods to normalize a vector in Unity - both in C# and in a shader.

This is a series on Unity Physics. We recommend reading the series in order.

  1. Unity Physics
  2. Unity Collision Detection
  3. Character Controller and Input Systems
  4. Rigidbody Mass in Unity
  5. How to add Friction to a Rigidbody
  6. Cylinder Collider in Unity
  7. Box Collider in Unity
  8. Box Cast in Unity
  9. Sorting Layers
  10. Get the distance between two objects
  11. How to normalize a vector

Introduction

Before diving into vector normalization, let us first understand the context.

In this section, we will explain what a vector is. And, we will look into why we want to normalize it.

In simple terms, a vector is an object that represents the magnitude and direction of a line in space. The magnitude means the size, or total length, of the vector.

You can have 2D, 3D, or n-dimensional vectors. Developers use vectors to describe velocity, force, and position. They also use vectors to describe direction.

I will give an example. A game developer uses a vector to describe the view direction of a camera. Let’s imagine that the camera looks straight ahead. In that case, the view direction (x, y, z) is equal to (0, 0, 1). They also use vectors to describe the direction in which a character should move. And, they use vectors to compare the position of two objects.

What is Vector Normalization?

Vector normalization is the process of transforming any vector into a unit vector.

A unit vector is a vector with a length (or magnitude) of 1 unit. When we normalize a vector, we throw away the original magnitude. But, we keep the direction.

Why would we want to throw away some information? Well, this helps us when using other operations to compare two vectors.

For example, you can use the dot product to compare two vectors. The dot product helps us understand how much the two vectors point in the same direction.

This also helps when you want an input vector to be the same length in every direction. In Unity, you will normalize a player’s input. This makes sure that the player moves the same speed in every direction.

How to calculate a normalized vector?

To better understand how this works, let’s take a quick math detour.

In this section, we will look at the math formula you need to normalize a vector.

You need to divide each component of the vector by the length of the vector. The magnitude is the length, or size, of the vector. You can calculate it using the Pythagorean theorem.

You can write the formula to normalize a vector v with components (x, y, z) like this:

vectorNormalized = v / ||v||

In this case, vectorNormalized is the output unit vector. v is the original vector. And, ||v|| represents the size (length) of vector v.

To compare two vectors, it is important that your vectors are in the same coordinate system when you normalize them.

How to normalize vector

Normalizing a vector involves a few simple steps. Let’s go through them to understand the process.

Step 1: Calculate the Magnitude of the Vector

To calculate the magnitude of a vector, use the following formula:

float vectorLength = Mathf.Sqrt(x*x + y*y + z*z)

Here, x, y, and z represent the components of the vector.

The Magnitude is also sometimes called the Length of the vector. As you can see, this calculation involves a square root.

Square roots can be expensive for performance. So, developers try to avoid them in their code. One technique to avoid a square root is to compare the results before the square root. The squared magnitude is the magnitude before we take the square root. Developers compare the squared magnitude to avoid taking the square root. Pretty clever, right?

You can compare the length of two vectors without using square root. I use this approach myself in my assets. For example, in Buto, I use the squared magnitude to compare a list of lights. Then, I return the closest lights. This is faster than calculating the square root for each light.

Step 2: Divide Each Component by the Length

Next, divide each component of the vector. The divisor is the length of the vector.

float xNormalized = x / vectorLength
float yNormalized = y / vectorLength
float zNormalized = z / vectorLength

Step 3: Normalize the Vector

Finally, we get the normalized vector by combining the normalized components:

Vector3 vectorNormalized = new Vector3(xNormalized , yNormalized , zNormalized)

Methods to Normalize a Vector in Unity using C#

Vectors in C# in Unity are special types. They are part of the UnityEngine library. Unity includes static methods that make it easy to normalize a Vector type. Unity also includes a normalized property for the struct.

To call the static method, you can call Vector3.Normalize(x), like this:

Vector3 vector = new Vector3(1,0,0);
Vector3 normalizedVector = Vector3.Normalize(vector);

To use the property accessor instead, you can access the .normalized property, like this:

Vector3 vector = new Vector3(1,0,0);
Vector3 normalizedVector = vector.normalized;

Methods to Normalize a Vector in Unity in a Shader

Vectors in HLSL in Unity are basic types. An example of a basic type is a float or an int. But, a vector has multiple components. A float with two components is called a float2. A float with three components is called a float3. It is the same with integers. An integer with two components is called an int2. You also see these types pop up in the Unity math library.

To normalize a vector like this in HLSL, you can call the normalize(x) intrinsic, like this:

float3 vector = float3(1,0,0);
float3 normalizedVector = normalize(vector);

The method works on any size input, so you can pass in a float2, float3, or even a float4.

It works by dividing the input vector (x) by the length of x.

Why should I normalize a vector in Unity?

Vector normalization offers several benefits in various applications. In this section, we will review some of these benefits.

Simplify Calculations

Normalized vectors make it easier to do some calculations. Let’s call these length-sensitive calculations. Some length-sensitive operations include the dot product or the cross-product.

One common use-case for the dot product is to see how “aligned” two vectors are. This is really easy if the two vectors are normalized. In that case, the dot product returns a value between negative one and positive one.

When the magnitude of a vector is 1, you no longer need to re-scale the vector relative to the comparison vector. This makes it easier and faster to compute alignment between two vectors.

Ensure Consistent Scaling

By normalizing vectors, we remove their original magnitudes. This gives us vectors with a fixed length. This property can be very useful when we want to ensure consistent scaling of vectors. You will want consistent scaling in applications like computer graphics or physics simulations.

Ease Comparisons

Normalized vectors provide a common reference point for comparison. When you normalize a vector, the direction of that vector becomes the primary focus. This makes it easier to compare between two vectors based on their orientation.

I will give you a way of thinking about this. Imagine you want to compare two vectors, but the one vector is very short and the other vector is quite long. If you look only at the x coordinate of the vector, it can be difficult to tell which one points more along the x axis. If you normalize the two vectors, it is obvious. The one that points more along the x axis is the one with the greater x coordinate.

Real-world scenarios

Vectors are used in all sorts of contexts. It is important to be familiar with vectors and with vector normalization. If you are, then you will be set to succeed in these fields.

Graphics and Rendering

Developers use vectors for various calculations. Some common examples include lighting and reflections. These types of calculations are common in graphics rendering. One common operation is the dot product. The dot product tells you how much two vectors point in the same direction.

When you use the dot product with two normalized vectors, you get back a scalar value between -1 and 1. This number tells you how much these two vectors align with one another. A value of 1 means that they point in the same direction. A value of -1 means that they point in opposite directions.

Developers use this to understand how bright an object is. They do this by comparing the normal vector of a surface to the direction of the sun.

Use normalized vectors to create games that have realistic lighting and reflections.

Movement and Physics

This is also important in movement and physics. When a player provides a movement input, you get that input as a vector. Imagine that you are using a two-dimensional vector (x, y).

If the player wants to move right, the vector you see is (1, 0). So, you move the player one unit to the right.

If the player wants to move up, the vector you see is (0, 1). So, you move the player one unit up.

If the player wants to move up and to the right, the vector you see is (1, 1). So, you move the player one unit up and one unit to the right.

But, wait - that’s not right! The player moved two steps instead of one. They moved too far. The player is moving too fast when moving on a diagonal. You need to normalize this vector. Then, the player will only move one unit in the combined direction. If you don’t, then players will move faster when moving on a diagonal.

As you can see, it is important that you normalize this vector. You ensure that your movement is consistent by normalizing the movement input before applying it. This helps to avoid movement bugs.

Conclusion

Vector normalization is a standard operation when working with vectors. This operation transforms any vector into a unit vector. As you’ve learned, normalizing a vector helps to simplify calculations. It helps to ensure consistent scaling. And, it simplifies comparisons between two vectors. By following the steps outlined in this article, you can normalize any vector using Unity in both C# and in your shaders. Thanks for reading!

FAQs

Q: Does normalizing a vector affect its direction?

A: No, the output vector will still point in the same direction as the input vector. But, the individual components of the vector will change. As a result, the output vector will have a length of 1 unit.

Q: Is vector normalization the same as vector scaling?

A: No. When you scale a vector, you re-size each component of the vector based on a scaling factor. When you normalize a vector, you re-size each component of the vector based on the original length of the vector.

Q: Can I normalize a vector with zero magnitude?

A: No, you can’t normalize a vector that has zero magnitude. That’s because this process involves dividing each component by the length of the vector. If the length is zero, then you would be trying to divide by zero.

Division by zero is undefined. So, the result is also undefined. In practice, Unity’s Normalize methods handle this situation for you. Unity’s method returns a new Vector set to (0, 0, 0). So, no need to worry about errors.

More reading

If you would like to continue learning about this topic, I put together some links for you.

These links cover technical content from Unity. And, they also cover non-technical content from Khan Academy and Stack Overflow.

Want to build better games?

© 2024