Search Unity

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

Discussion in 'Shaders' started by Isomania, Jul 1, 2022.

  1. Isomania

    Isomania

    Joined:
    Jan 28, 2021
    Posts:
    16
    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 :).
     
    Last edited: Jul 2, 2022
  2. Isomania

    Isomania

    Joined:
    Jan 28, 2021
    Posts:
    16
    I'am dumb :)

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

    Code (CSharp):
    1. // remove T (translation) from TRS (translation, rotation, scalar) matrix
    2. 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!
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,338
    There’s an easier solution.

    Code (csharp):
    1. mul(UNITY_MATRIX_VP, float4(worldPos.xyz, 0.0))
     
    Isomania likes this.
  4. Isomania

    Isomania

    Joined:
    Jan 28, 2021
    Posts:
    16
    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 :D
     
  5. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,924
    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).
     
    Last edited: Jul 6, 2022
    Isomania likes this.