Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

How can I get spot light direction in forward add pass?

Discussion in 'Shaders' started by dtysky, Jun 21, 2019.

  1. dtysky

    dtysky

    Joined:
    Jul 10, 2018
    Posts:
    2
    Hi everyone, I am writing my own PBR shader that uses physic lights, so it needs `range`, `direction` and `angle` of spot lights. I have get the `range` and `angle` by some trick, but has no idea that how to get `direction`:

    Code (CSharp):
    1. #if defined (SPOT)
    2.     float4 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1));
    3.     float range = length(distanceVec) / length(lightCoord.xyz);
    4.     float attenuation = getLightAttenuation(distanceVec, range);
    5.     float cotanHalfSpotAngle = 2. * lightCoord.z / lightCoord.w;
    6.  
    7.     // a trial, but not working
    8.     float3 lightSpaceUnitDir = float3(0., 0., 1.);
    9.     float3 worldLightUnitDir = mul(lightSpaceUnitDir, inverse((float3x3)unity_WorldToLight));
    10.     pbr.L = mul(UNITY_MATRIX_V, worldLightUnitDir);
    11.  
    12.     float outerCutoff = atan(1. / cotanHalfSpotAngle);
    13.     float cutoff = max(outerCutoff - .05, 0.);
    14.     float theta = dot(normalize(distanceVec), pbr.L);
    15.     float epsilon = cos(outerCutoff) - cos(cutoff);
    16.     float intensity = clamp((theta - cos(cutoff)) / epsilon, 0.0, 1.0);
    17.     attenuation *= intensity;
    18. #endif
    How can I get it? Why does not unity give us this information when we need to calculate attenuation ourselves?

    Thanks!
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    6,970
    For a spotlight, the unity_WorldToLight matrix is a transform and perspective matrix, which makes things a little funny. However you're pretty close already:

    float3 worldLightUnitDir = normalize(mul(float3(0,0,1), (float3x3)unity_WorldToLight));

    For an orthogonal matrix, the transpose and the inverse are the same, and doing the mul in vector matrix order applies the matrix as transposed vs matrix vector order. This only works because the forward axis of the matrix isn't affected by the perspective, but it does work.
     
  3. dtysky

    dtysky

    Joined:
    Jul 10, 2018
    Posts:
    2
    Thanks! You save my time ! I finally solve this problem by `float3 worldLightUnitDir = normalize(mul(float3(0,0,-1 (float3x3)unity_WorldToLight));`