Search Unity

Resolved How do I use Matrix4x4.TRS inside a vertex shader?

Discussion in 'Shaders' started by Buttermilch, Jul 26, 2022.

  1. Buttermilch

    Buttermilch

    Joined:
    Nov 23, 2016
    Posts:
    33
    I'm trying to instantiate a lot of objects with
    Graphics.DrawMeshInstancedIndirect()

    I have a shader with a compute buffer that contains an array of Matrix4x4 TRS.
    But how do I use these matrices to position, scale and rotate the object inside a vertex shader?

    Or is there a better approach to do this?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Those transform matrices are how (almost) all shaders transform any mesh from local object space to world, or view, or clip space, or any other kind of transform. They fast and efficient. For example most Unity shaders have something like this line in the vertex shader:
    Code (csharp):
    1. o.pos = UnityObjectToClipPos(v.vertex);
    That
    UnityObjectToClipPos()
    funciton is defined like this:
    Code (csharp):
    1. float4 UnityObjectToClipPos(float3 vertex)
    2. {
    3.   return mul(UNITY_MATRIX_VP, mul(unity_ObjectToWorld, float4(vertex, 1.0));
    4. }
    Those
    UNITY_MATRIX_VP
    and
    unity_ObjectToWorld
    variables are
    float4x4
    transform matrices, equivalent to Unity's C# Matrix4x4. One transforms the vertex position form object to world space, as you can probably guess from the name, and the other from world space to clip space. Clip space is a sort of special screen space position used by the GPU to calculate the actual screen space position, as well as handle perspective correct UV distortions. You don't really need to understand that last part too much, but if your transform matrices are to transform your instanced mesh from local object space to world space, then you can just replace that
    unity_ObjectToWorld
    transform before that
    UnityObjectToClipPos()
    function gets called. If the shader is using normal mapping, you'll also need to override the
    unity_WorldToObject
    transform matrix, which if you're only using uniform scaling, can be approximated with:
    Code (csharp):
    1. unity_ObjectToWorld = MyTRSBuffer[Index];
    2. unity_WorldToObject = transpose(unity_ObjectToWorld);