Vertex light causes lighting "pop" on objects

Hey,

I am using a lot of vertex point lights in my scene and when they pass by an object, as soon as the object is out of range, it will cause a noticeable popping of the light turning off. I did some tests with a single point light and object and I get the same results. It seems at the very outer edge of the light radius it does not attenuate to 0 and as a result, as soon as a vertex enters the range, it causes the object to light up significantly.

Is this a bug or just how vertex lights work? I would think that there would be a smooth transition from 0 to 1 intensity within the light range.

Any help would be greatly appreciated as I can’t really use pixel lights for my current project.

Thanks!

There’s a limit to the number of lights than can be rendered on an object in forward rendering. You get a single directional light, a default of 4 per-pixel lights, and 4 vertex lights. Any beyond that get added to the object’s “ambient light”, but only if the light is hitting the object’s center. If you have >4 vertex lights touching an object it tries to use the 4 brightest or closest lights, and if you have any per pixel lights enabled one of those vertex lights might be a blended per pixel light.

1 Like

Thanks for the response, bgolus. I thought it might be an issue with reaching the maximum light capacity but I get the same problem even in a new scene with 1 cube and 1 point light. You can see the difference in brightness in the attached image. It looks subtle there but when you see it popping in it’s quite noticeable.

It seems like the issue is with the light attenuation on vertex point lights. I noticed this thread that describes how to change the light attenuation for deferred rendering: Easiest way to change Point Light attenuation ? (with Deferred path) - Unity Engine - Unity Discussions , but I am looking for a solution for forward rendering and vertex lighting because I’m making a mobile VR game.

Anyone know how to change the attenuation on a vertex point light for forward rendering?

The bit of code that’s important is in UnityCG.cginc:

float3 Shade4PointLights (
    float4 lightPosX, float4 lightPosY, float4 lightPosZ,
    float3 lightColor0, float3 lightColor1, float3 lightColor2, float3 lightColor3,
    float4 lightAttenSq,
    float3 pos, float3 normal)
{
    // to light vectors
    float4 toLightX = lightPosX - pos.x;
    float4 toLightY = lightPosY - pos.y;
    float4 toLightZ = lightPosZ - pos.z;
    // squared lengths
    float4 lengthSq = 0;
    lengthSq += toLightX * toLightX;
    lengthSq += toLightY * toLightY;
    lengthSq += toLightZ * toLightZ;
    // NdotL
    float4 ndotl = 0;
    ndotl += toLightX * normal.x;
    ndotl += toLightY * normal.y;
    ndotl += toLightZ * normal.z;
    // correct NdotL
    float4 corr = rsqrt(lengthSq);
    ndotl = max (float4(0,0,0,0), ndotl * corr);
    // attenuation
    float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
    float4 diff = ndotl * atten;
    // final color
    float3 col = 0;
    col += lightColor0 * diff.x;
    col += lightColor1 * diff.y;
    col += lightColor2 * diff.z;
    col += lightColor3 * diff.w;
    return col;
}

That atten function results in a falloff that is a “bit” larger than a per pixel point light (in fact it’s infinite), which is ultimately what’s causing the popping. I’m not sure what calculation is used to build the lookup texture used by per pixel lights, but I suspect it’s similar but with a distance clamp.

Thanks for the response. Unfortunately, editing that code is beyond my capabilities. I don’t have much experience with custom shaders or lighting calculations like this.

If anyone is able to edit the code to reduce/eliminate the light attenuation popping that would be awesome, otherwise I’ll have to pursue other options.