# Scaling Matrix

The simplest of the four 3D matrix types is the Scaling matrix.

In this context, “scaling” means to make a shape larger or smaller by multiplying a vector by a scalar value.

Given a data type Vector4:

struct Vector4 { float X; float Y; float Z; float W; }; 

A simple way to scale a vector might be:

 Vector4 Scale(const Vector4& v, const float uniformScale) { return Vector4(v.x * uniformScale, v.y * uniformScale, v.z * uniformScale, v.w); } 

However, if we plan on performing this operation on lots of data points – say, in a vertex shader which operates on every vertex in our model, we’d like to use a matrix so that the scale operation can be combined with our rotation, translation and projection operations. Given an identity matrix:

$$\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix} \\$$

and remembering that in a row-major matrix such as this, each row represents a basis vector of a transformed coordinate system. The values on the diagonal of an identity matrix represent a coordinate system that has a scale of 1. Not very exciting.

To create a scaling matrix, we’ll multiply the values on the diagonal with our scale vector

$$\vec{s} = (s_x, s_y, s_z, 1)$$

which gives us:

$$\begin{bmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}$$

Notes:

1. The the W component of the last row (bottom right corner of the matrix) is NOT modified, as we are only concerned with scaling in X, Y and Z. Scaling W leads to interesting side effects.
2. Although this example allows for $$\vec{s}$$ to have different values for its $$(s_x, s_y, s_z)$$ components, we will usually want these all to be the same number for uniform scaling.