Removing position from matrix (Decompose TRS to RS in shader)

Hi!

I want to transform a worldposition (that i already have) to camera clipspace, ignoring camera position. IE just the rotation/scaling (if there is any scaling in UNITY_MATRIX_VP ofc).

Imagine if you will, a camera with the same rotation/scale as main but at worldpos (0,0,0)

Would prefer for you to answer with code and not shadergraph :).

I’am dumb :slight_smile:

All I had to do was to set _m03_m13_m23 to 0.0.

// remove T (translation) from TRS (translation, rotation, scalar) matrix
UNITY_MATRIX_VP._m03_m13_m23 = 0.0;

Keep in mind that anything using UNITY_MATRIX_VP will now not work as intended, like UnityObjectToClipPos. So remove the translation after you’ve used them, or change it back after you are done!

There’s an easier solution.

mul(UNITY_MATRIX_VP, float4(worldPos.xyz, 0.0))
1 Like

So if I preform a matrix multiplication with float4.w set to 0.0, I ignore all translations?
I’ve always set it to 1.0, and thought nothing of it :smile:

That’s correct. Setting the fourth component of the vector to 0, treats it as a direction instead of a point. The reason is that the fourth column of the matrix (where translation resides) gets multiplied by zero instead of one, so (0,0,0) translation is added to the result.

This is the same result you’d get in C# by using Unity’s TransformVector() function (rotation + scale).
Using TransformPoint() would be equivalent to having the .w set to 1, hence including translation (rotation + scale + translation).

On the other hand, TransformDirection() does not translate or scale the vector: it only rotates it, keeping its length. This is not easy to replicate if your transform is in matrix form, as you’d have to decompose its upper 3x3 submatrix into rotation and scale.

Internally Unity does not store transforms as a matrix, but as separate translation, scale and rotation values so they’re easy to apply individually (or build a matrix from them when required).

1 Like