Search Unity

Create a float3 from a Matrix4x4

Discussion in 'Shaders' started by Dimlos, Dec 4, 2018.

  1. Dimlos

    Dimlos

    Joined:
    Aug 13, 2014
    Posts:
    51
    Hello.
    I'm mainly using Amplify Shadder but for a specific effect I had to go into the code generated by the pluggin.

    I was using from a script "SetVectorArray" to Update an array of positions in the Shader.
    It worked but it was pretty heavy.
    So I tried to replace that by using Matrix4x4 set to half to see if it was faster, but since I'm not used to code a shader directly I'm having trouble fixing it, here is the part causing me problems:

    Code (CSharp):
    1.  
    2. float3 pos1 = 0;
    3. float3 pos2 = 0;
    4. float3 pos3 = 0;
    5. float3 pos4 = 0;
    6.  
    7. for (int i = 0; i < 4; i++)
    8. {
    9.    switch(i)
    10.    {
    11.    case 0:
    12.        for (int u = 0; u < 3; u++)
    13.            pos1[u] = PositionMatrix[i,u];
    14.        break;
    15.    case 1:
    16.        for (int o = 0; o < 3; o++)
    17.            pos2[o] = PositionMatrix[i,o];
    18.        break;
    19.    case 2:
    20.        for (int p = 0; p < 3; p++)
    21.            pos3[p] = PositionMatrix[i,p];
    22.        break;
    23.    case 3:
    24.        for (int m = 0; m < 3; m++)
    25.            pos4[m] = PositionMatrix[i,m];
    26.        break;
    27.    }
    28. }
    29. }

    I want to save 4 positions sent by a script from this matrix, and then do stuff with it.
    But it looks like every "pos" are the exact same even if I can clearly see in my script that I'm sending a matrix with different values inside.
    I guess they are the same values because if I comment out every cases except one and test them one by one, they all display what I want at the first position when they should be displaying it the their respective positions..

    If I take for exemple the first loop I tried to replace it by several things, listed bellow:

    Code (CSharp):
    1. case 0:
    2.     pos1[u] = PositionMatrix[i][u];
    3. break;
    4. ----------------------------------------------------------------------------------------------------
    5. case 0:
    6.     pos1[u] = PositionMatrix.this[i,u];    //error: "invalid subscript 'this'"
    7. break;
    8. ----------------------------------------------------------------------------------------------------
    9. //removing the loop:
    10. case 0:
    11.     pos1 = float3(PositionMatrix[0,0], PositionMatrix[1,0], PositionMatrix[2,0]);
    12. break;
    13. //but I get : "incorrect number of arguments to numeric-type constructor"

    I've spend way too much time on this little thing and I don't even know if it'll give me any performance boost.
    I just want to get those matrix4x4 floats and make float3 with them.
    I hope you can help me.
    Thank you.
     
    Last edited: Dec 4, 2018
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Wow, an iterator in a switch in a interator. That's a lot of inefficient code to do what can be done with out any of that.

    Here's the way to access elements of a matrix in HLSL:
    https://docs.microsoft.com/en-us/wi...phics-hlsl-per-component-math#the-matrix-type

    float3 pos0 = PositionMatrix._m00_m01_m02;
    float3 pos1 = PositionMatrix._m10_m11_m12;
    float3 pos2 = PositionMatrix._m20_m21_m22;
    float3 pos3 = PositionMatrix._m30_m31_m32;

    And done. Don’t do anything more. Just output those 4 values from your custom node and use them as needed. These are row-column indices, so make sure you're using matrix.SetRow() in c#.

    Also it probably won’t have any affect on your performance.
     
  3. Dimlos

    Dimlos

    Joined:
    Aug 13, 2014
    Posts:
    51
    Ok I looked into what you said and it worked.
    I got way better performances but it was mostly because I re-made my c# code sending the matrix.
    I was checking collisions on multiple objets to get serveral materials but that was not needed since I could set any global variable with Shader.SetGlobalMatrix();

    I was using loops and a switch because in my head "loops go fast!" and I was desperate to go around some errors I was getting since it doesn't really work exactly the same as coding a regular code.
    I'm self taught so I'm probably making several dumb mistakes here and there in my game code.
    It's ambarassing but even tho I searched everywhere for shader informations, I never realised that they are written in HLSL, so I couldn't find any API
    Thank you for the fast reply.
     
    Last edited: Dec 5, 2018