Search Unity

How do you calculate unity_WorldToLight/_LightMatrix0 matrix for directional light in C#?

Discussion in 'Shaders' started by smoore2171, Apr 24, 2022.

  1. smoore2171

    smoore2171

    Joined:
    Jul 14, 2014
    Posts:
    9
    I need to calculate the world-to-light matrix (the shader properties unity_WorldToLight/_LightMatrix0) for a directional light on the sim/C# side of things. There is no accessor on the light for this, and it is only passed into shaders. I figure it is just an ortho projection matrix for the light, but my math is failing me. Anyone know how to calculate this?

    I want this to help customize a deferred shader a bit more for the single global light cookie in my scenes. Since it doesn't have access to this in the shader, I was just going to pass the texture in myself, but I need this matrix to calculate the attenuation correctly.

    I have something like
    Matrix4x4 modelView = Matrix4x4.LookAt(m_Light.transform.position, m_Light.transform.position + m_Light.transform.forward, Vector3.up);
    Matrix4x4 lightProjectionMatrix = Matrix4x4.Ortho(-cookieWorldSize, cookieWorldSize, -cookieWorldSize, ciijueWorldSize, 0.1f, 100000) * modelView;

    I'm also passing it through GL.GetGPUProjectionMatrix after calculation.


    but I know this is wrong. If someone with better math skills can help, I'd appreciate it. I'm also unsure if unity scales the actual texture by cookieWorld size and then uses the standard projection matrix or scales that into the matrix itself.
     
    Last edited: Apr 24, 2022
  2. smoore2171

    smoore2171

    Joined:
    Jul 14, 2014
    Posts:
    9
    Code (CSharp):
    1.            
    2.             Matrix4x4 modelView = Matrix4x4.LookAt(m_Light.transform.position, m_Light.transform.position + m_Light.transform.forward, m_Light.transform.up);
    3.             float cookieSize = m_WorldSize;
    4.             Matrix4x4 newModel = new Matrix4x4();
    5.             Matrix4x4.Inverse3DAffine(modelView, ref newModel);
    6.             Matrix4x4 worldToLight = GL.GetGPUProjectionMatrix(Matrix4x4.Ortho(-cookieSize, cookieSize, -cookieSize, cookieSize, 0.1f, cookieSize), false) * newModel;
    7.  
    This is closer, the scale and skew is right, and the scrolling texture is always in the correct direction no matter how I change light direction (compared to it on the standard shader), but it is still offset.
     
    Last edited: Apr 24, 2022
  3. smoore2171

    smoore2171

    Joined:
    Jul 14, 2014
    Posts:
    9
    I'm missing the position component of the light, which I guess is factored in for cookie... Matrix4x4.TRS instead of LookAt doesn't seem to make a difference though...
     
  4. smoore2171

    smoore2171

    Joined:
    Jul 14, 2014
    Posts:
    9
    If I just offset the final translation by 0.5f, then everything works all the time, but not quite sure where this comes from.