Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Set variables and debug vertex shaders

Discussion in 'Shaders' started by HibsStatement, Jun 9, 2023.

  1. HibsStatement

    HibsStatement

    Joined:
    Jan 31, 2022
    Posts:
    31
    I am trying to transform vertices in a vertex shader based on a custom ModelMatrix and ViewMatrix. On the CPU, when I run the code, the outputs are as expected, but the shader is not giving a desired result.

    Currently, I am setting the matrices in the `Update()` method like this:

    Code (CSharp):
    1.         private void Update()
    2.         {
    3.             material.SetMatrix("_NewModelMatrix", _transform.GetModelMatrix());
    4.             material.SetMatrix("_NewViewMatrix", _camera.GetViewMatrix());
    5.             material.SetMatrix("_NewInvViewMatrix", _camera.GetInverseViewMatrix());
    6.         }
    and in the Shader, i have them like this:


    Code (CSharp):
    1.             float4x4 _NewModelMatrix;
    2.             float4x4 _NewViewMatrix;
    3.             float4x4 _NewInvViewMatrix;
    I wonder if my approach here is correct, setting vertex shader matrices in the `Update()` method. Because the output is not the desired result.

    Also, if I use the regular Unity calculation:

    Code (CSharp):
    1. o.vertex = mul(mul(UNITY_MATRIX_P, UNITY_MATRIX_V), mul(unity_ObjectToWorld, float4(v.vertex)));
    but replace the matrices with my versions, nothing happens. So I'm pretty sure the matrices are not being sent to the shader correctly.

    I was wondering if someone can explain to me if my approach here is correct, or possibly provide me with options to debug my issue, since debugging vertex shaders is not so straightforward.
     
    Last edited: Jun 9, 2023
  2. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    314
    For performance reasons, it is better to calculate MVP matrix on C# side, then send just one matrix to shader:

    Code (CSharp):
    1. Matrix4x4 mvp = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false) * camera.worldToCameraMatrix * renderer.localToWorldMatrix;
    2. material.SetMatrix("_MVP", mvp);
    If all three matrices must be used in shader, first calculate MVP matrix, then multiply vertex from object to clip space:
    Code (CSharp):
    1. float4x4 mvp = mul(mul(UNITY_MATRIX_P, UNITY_MATRIX_V), unity_ObjectToWorld);
    2. o.vertex = mul(mvp, float4(v.vertex.xyz, 1.0));
    To debug matrices in Unity, you can use Profiler. For example, add cube to empty scene, set forward rendering in camera rendering path, add material to cube, press Play, then select Window -> Analysis -> Profiler. Then Rendering -> Open Frame Debugger.

    Code (CSharp):
    1. Shader "Blue"
    2. {
    3.     SubShader
    4.     {
    5.         Pass
    6.         {
    7.             CGPROGRAM
    8.             #pragma vertex VSMain
    9.             #pragma fragment PSMain
    10.  
    11.             float4x4 _Matrix;
    12.  
    13.             float4 VSMain (float4 vertex : POSITION, inout float2 uv : TEXCOORD0) : SV_POSITION
    14.             {
    15.                 return UnityObjectToClipPos(vertex);
    16.             }
    17.  
    18.             float4 PSMain (float4 vertex : SV_POSITION, float2 uv : TEXCOORD0) : SV_TARGET
    19.             {
    20.                 return mul(_Matrix,float4(0,0,1,1));
    21.             }
    22.             ENDCG
    23.         }
    24.     }
    25. }
    Matrix "_Matrix" isn't set by C# SetMatrix(), so it has default value (matrix identity).

    upload_2023-6-9_20-13-50.png

    If you would like to get more detailed info, read this topic:

    https://forum.unity.com/threads/how-to-print-shaders-var-please.26052/#post-5160875

    If you want to learn more, there is a MVP matrix calculator, written from scratch (link to file in video description):

     
    Last edited: Jun 9, 2023
    HibsStatement likes this.
  3. HibsStatement

    HibsStatement

    Joined:
    Jan 31, 2022
    Posts:
    31

    Thank you for taking the time to explain this to me.

    First of all, I did not know about the Frame Debug window, so thank you.

    After looking at this window, I can confirm that none of the 3 matrices I defined in the shader:


    Code (CSharp):
    1.             float4x4 _NewModelMatrix;
    2.             float4x4 _NewViewMatrix;
    3.             float4x4 _NewInvViewMatrix;
    Are being sent to the shader correctly:

    upload_2023-6-9_21-7-13.png

    I wonder, how can I send my own custom matrices to the shader? As you pointed out, doing:

    Code (CSharp):
    1.             material.SetMatrix(NewModelMatrix, _transform.GetModelMatrix());
    2.             material.SetMatrix(NewViewMatrix, _camera.GetViewMatrix());
    3.             material.SetMatrix(NewInvViewMatrix, _camera.GetInverseViewMatrix());
    will not set the matrices accordingly. Although you seem to be getting an Identity matrix, I dont get anything displayed.
     
  4. Przemyslaw_Zaworski

    Przemyslaw_Zaworski

    Joined:
    Jun 9, 2017
    Posts:
    314
    You have to "use" your variables in code (inside vertex / pixel shader), otherwise it will be excluded from compilation and finally not visible in profiler. In this example I use _Matrix in line nr 17:

    Code (CSharp):
    1. Shader "Blue"
    2. {
    3.     SubShader
    4.     {
    5.         Pass
    6.         {
    7.             CGPROGRAM
    8.             #pragma vertex VSMain
    9.             #pragma fragment PSMain
    10.             float4x4 _Matrix;
    11.             float4 VSMain (float4 vertex : POSITION, inout float2 uv : TEXCOORD0) : SV_POSITION
    12.             {
    13.                 return UnityObjectToClipPos(vertex);
    14.             }
    15.             float4 PSMain (float4 vertex : SV_POSITION, float2 uv : TEXCOORD0) : SV_TARGET
    16.             {
    17.                 return mul(_Matrix,float4(0,0,1,1));
    18.             }
    19.             ENDCG
    20.         }
    21.     }
    22. }
     
    HibsStatement likes this.
  5. HibsStatement

    HibsStatement

    Joined:
    Jan 31, 2022
    Posts:
    31
    Yes, I was still using my temporary Unity version for testing, so it wasn't displaying them.

    I am indeed seeing my matrices properly showing up in the profiler now. My shader is still bugging, but atleast my questions have been answered, Thanks!