Reproducing Camera's worldToCameraMatrix

I’d like to be able to generate the worldToCameraMatrix myself without using the worldToCameraMatrix field on the Camera class (I’m planning on calculating an optimal camera position in a separate thread).

	Matrix4x4 matrix1 = camera.worldToCameraMatrix;
	Matrix4x4 matrix2 = Matrix4x4.TRS (
		new Vector3(camera.transform.position.x, camera.transform.position.y, -camera.transform.position.z),
		camera.transform.rotation, 
		Vector3.one
	);

I believe the Z direction is flipped in camera space so I’m negating the z position. The code above doesn’t result in the same matrix for matrix1 and matrix2. What is the right code to set the matrix2 variable above so matrix1 matches matrix2 without using camera.worldToCameraMatrix ?

1 Like

Awww, was hoping this was an easy answer for the right person.

All the worldToCameraMatrix is, is the worldToLocalMatrix using OpenGL standards.

As the documentation says:

So, if you can calculate the ‘worldToLocalMatrix’, just negate the entire 3rd row of the matrix (the z portions).

‘worldToLocalMatrix’ can be calculated as the inverse of ‘localToWorldMatrix’. And the localToWorldMatrix is just a matrix of the world position, rotation, and scale (the TRS).

So something like this:

var m = Matrix4x4(camera.transform.position, camera.transform.rotation, Vector3.one); //no scale...
m = Matrix4x4.Inverse(m);
m.m20 *= -1f;
m.m21 *= -1f;
m.m22 *= -1f;
m.m23 *= -1f;
7 Likes

Genius, that works. Much appreciated.

Or simply:

viewMatrix = Matrix4x4.Inverse(Matrix4x4.TRS(
  camera.transform.position,
  camera.transform.rotation,
  new Vector3(1, 1, -1)
) );
6 Likes