# How do I make 2D Camera Matrix with zoom?

I trying to understand how to make a 2D Camera Matrix. The problem now is when I zoom the world shifts horizontally. The Camera need to zoom on the current Position.

public class MyCamera
{
public Vector2 Position;
public float Zoom;
public Matrix2D Transform = Matrix2D.identity;

public void Update()
{
Vector2 screen = new Vector2(Screen.width, Screen.height);

Transform = Matrix2D.Translate(-Position) *
Matrix2D.Scale(new Vector2(Zoom, Zoom)) *
Matrix2D.Translate(screen / 2);
}
}

public class MyGame
{
MyCamera Camera = new MyCamera();

Sprite TestImage;
float Zoom;
float ScrollSpeed = 0.2f;

public void Update()
{
Vector2 size = new Vector2(Screen.width, Screen.height);
Zoom += Input.mouseScrollDelta.y * ScrollSpeed;

Camera.Zoom = Zoom;
Camera.Position = Input.mousePosition;
Camera.Update();

//Update my sprite
TestImage.Position = Camera.Transform.MultiplyPoint(Vector2.zero);
TestImage.Size = Camera.Transform.MultiplyVector(new Vector2(512, 512));
}
}


• What framework do you use? Jun 27, 2021 at 16:29
• For this demo I use Unity to test my code, but I'm gonna convert this to JavaScript. So I can not use the build in Camera from Unity. I only need to know how to use the Matrix calculation. Jun 27, 2021 at 16:48

Unity

In Unity, there is no such as 2D rendering. Transforms will always have three component Vectors, and Quaternions which support representations of three-dimensional rotations. If your camera is set to perspective, then you can simply move the camera along the z-axis to zoom in/out. If your camera is orthographic, then you can just change the orthographicSize of you your camera.

In General

The reality that 2D doesn't really exist in Unity from a rendering POV, is the same case for most low-level 2D APIs that I know of. If you're converting your code to JS and using webGL 3D, then you'll still be passing 4x4 matrices through the rendering pipeline (last column and row are for translations) even if your game logic is all in 2D. Then the same strategies that I outlined above, which depend on whether your camera is perspectived' or orthographic, will work. If you're using webGL 2D, then just use a normal scale matrix, and multiply it with your perspective, rotation and translation matrices to get your final camera matrix.

$$\begin{pmatrix} scale & 0 \\ 0 & scale \end{pmatrix}$$

Order of matrix multiplications

I realize that one of the things you might be struggling with, is the order of matrix multiplications. It seems you understand that a scale-matrix is needed, but in order for a scale to have the visual effect of zooming the scaling has to be done from the camera view's center. This means that before you apply the scale-matrix/zoom, you have to first get all the sprites into camera-space (with the camera at (0,0), pointing directly forward).

Otherwise a scale matrix will have the visual effect of making sprites look like they're getting bigger/smaller from some arbitrary anchor point. Or it'll look like you're zooming and panning the camera in an unpredictable and uncontrollable manner.

These are fundamental graphics programming topics though, so you'll be able to find really great tutorials out there online.