# 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));`