Obtaining light distance in Surface Shader

Background
I am trying to implement a Translucent Shader in Unity’s surface shader system. The problem with this effect is that it requires access to the light’s attenuation factor by itself without shadowing. Unfortunately, there does not appear to be a way to access this in the surface shaders.

So I concluded that I need to calculate my own attenuation factor directly, but this approach could be expensive.

Questions

  • Is there any cheap way to obtain the light distance to a point?
  • Is my only option to use mul(_LightMatrix0, IN.worldPos).z?
  • Is there a less clumsy option for obtaining light attenuation that has been confirmed to work?

Thanks.

calculate the distance within the vertex program, using the _WorldSpaceLightPos0.
make sure to destinguish between directional and pointlights. (the w being 0.0 for directional)
distance would be: length(float3(_WorldSpaceLightPos0.xyz - IN.worldPos.xyz))
attentuation would probably be 1.0 / distance

consider a struct to pass the new values to the surface program. Where you could use a float4 to pass the lightdirection as xyz + attenuation as w, for usage.

Yeah, this is technically possible to access, but it’s a pain to get working (and it requires duplication of code and some more texcoords to push through, so it’s a fair bit less efficient).

I did figure it out, but I didn’t want to confuse the post by giving custom cginc files and more complex code.

@Farfarer
Yeah, I saw your posts on that, hence why I am just recalculating it. I really hate resorting to this option, but it really needs distance attenuation.

I’ll see if I’ve got the code kicking around for it and post it up later.