Simulating Unity's VertexLit shader with custom CG shader

Hey All,

I’ve begun learning CG Shaders (first time doing shaders at all) and ShaderLab with my first aim to create a vertex lit shader in CG that is near identical to Unity’s built-in VertexLit.

My main problem is that I’ve pasted in the exact shader from this unity wikibook page (CG Tutorials) and have tried to fiddle with the ‘attenuation’ variable in all manner of ways (searching google and forums far and wide) to simulate unity’s built-in VertexLit (Including AutoLight.cginc and fooling around with what it provides). Regardless of what I do I’m unable to make the attenuation of the shader match a simple Point Light’s Range and Intensity attributes like the built-in does, and it always ends up producing the effect described by the picture attached.

I’ve been going at it for so long now that I’m pretty much asking if someone is able to directly quote me exactly what I need to type in to that CG shader so that it’ll allow me to get the Range of the current point light as that would at least unstick me from this bog I’m currently in xD Would anyone be able to help?

Cheers in advance for any help, and thanks for viewing!

  • Edit: I managed to get a pixel light working via AutoLight.cginc’s LIGHT_ATTENUATION(a), is there any equivalent I can use inside of vertex instead of frag?

Just bumping to avoid creating a new thread, but I’ve managed to figure out the above problem via using unity_4LightAtten0 in my vertex program (can’t believe I managed to miss that the entire time) but I’m running into the same problem mentioned by Aras in this thread (second post down) about point light attenuation models never reaching zero. He mentions that “near the light’s range it fades to zero,” which sounds like a perfect solution for me but I can’t for the life of me figure out how you’d do that in a CG Shader, would anyone be able to lend me a hand on the matter? All I’d need is to know how to directly access the “Range” attribute of a point light but I’m rubbish with shader debugging and am unsure how to figure out what gives it to me.

Apologies for bumping and triple posting, but I appear to have completely solved my problem. I’ll detail why/how below, hope this’ll be useful to someone someday!

If the code for handling attenuation is as follows:

float squaredDistance = dot(vertexToLightSource, vertexToLightSource);
float attenuation = 1.0 / (unity_4LightAtten0[index] * squaredDistance);

where vertexToLightSource is literally the vector describing the difference between the vertex and the light source (in world space), then by simply appending the line:

if (attenuation < 0.04) attenuation = 0;

It cuts off the light at it’s Range attribute (set in the Unity Editor), I believe this has much to do with the attenuation equation mentioned by Aras in the thread linked above in the second post (as 0.04 == 1/25).

You’re still largely wasting performance thanks to the if statement, and there’s no guarantee it’ll run on webgl. In any case, it’s easy to fix. attenuation * step(attenuation, 0.04) will result in the same behaviour as the if statement, without the overhead for some platforms.

Might need to swap the order in the step.

Hey thanks man :slight_smile: Totally works as a replacement.
Still majorly new to everything shaders, I appreciate the help.

-Edit: Oh and yeah, I had to swap the order