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

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:

#if defined (SPOT)
    float4 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1));
    float range = length(distanceVec) / length(lightCoord.xyz);
    float attenuation = getLightAttenuation(distanceVec, range);
    float cotanHalfSpotAngle = 2. * lightCoord.z / lightCoord.w;
  
    // a trial, but not working
    float3 lightSpaceUnitDir = float3(0., 0., 1.);
    float3 worldLightUnitDir = mul(lightSpaceUnitDir, inverse((float3x3)unity_WorldToLight));
    pbr.L = mul(UNITY_MATRIX_V, worldLightUnitDir);
  
    float outerCutoff = atan(1. / cotanHalfSpotAngle);
    float cutoff = max(outerCutoff - .05, 0.);
    float theta = dot(normalize(distanceVec), pbr.L);
    float epsilon = cos(outerCutoff) - cos(cutoff);
    float intensity = clamp((theta - cos(cutoff)) / epsilon, 0.0, 1.0);
    attenuation *= intensity;
#endif

How can I get it? Why does not unity give us this information when we need to calculate attenuation ourselves?

Thanks!

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.

Thanks! You save my time ! I finally solve this problem by float3 worldLightUnitDir = normalize(mul(float3(0,0,-1 (float3x3)unity_WorldToLight));