2d Lighting - Each light draws 3 times in Frame Debugger

Hello, I'm trying to optimize my 2d game's rendering performance and could use some help.

Unity: 2021.3.33f1
Universal RP 12.1.13

I'm stepping through the Frame Debugger and noticed something curious - Each 2d light is rendered 3x before the lighting loop finishes. The screenshots below will show how I've determined this:

This is what the final render should look like. I've decreased the global light intensity and upped the 2d light's intensity to make it more obvious.

The Frame Debugger shows me that the 2d light drawing sequence (for Blend Style 0) starts with a "clear". So far so good:

Then it draws the first mesh. Still looking good:

But THEN it clears again, clears one more time, draws the same mesh again, clears again, then draws the mesh one more time:

All said and done, it takes 7 draw calls instead of 2. If I have more lights, it does this pattern:

Clear
Draw all n lights
Clear
Clear
Draw all n lights
Clear
Draw all n lights

So it's basically doing 2n+3 more draw calls than necessary.

Here are screenshots of the particular light in question, as well as my 2d Renderer Data

9713521--1388179--upload_2024-3-20_14-38-27.png 9713521--1388182--upload_2024-3-20_14-39-55.png

Can someone help me understand if this is expected, and why? Or does this seem like a misconfiguration of my lights? Any help would be greatly appreciated.

Thank you!

9713521--1388152--Screenshot 2024-03-20 at 2.20.09 PM.png
9713521--1388155--Screenshot 2024-03-20 at 2.20.22 PM.png
9713521--1388158--Screenshot 2024-03-20 at 2.20.26 PM.png

1 Like

Hi, I just ran into the same problem and every TargetSortingLayer defined in the Light2D gets its own texture (and therefore its own draw call). Some simple lighting in my Scene causes a 10FPS Framedrop on low-end devices. This stuff is way more expensive than I anticipated damn

[quote=“leohilbert”, post:2, topic: 942653]
Hi, I just ran into the same problem and every TargetSortingLayer defined in the Light2D gets its own texture (and therefore its own draw call). Some simple lighting in my Scene causes a 10FPS Framedrop on low-end devices. This stuff is way more expensive than I anticipated damn
[/quote]

According to this post , “all” you need to do is define the sorting layers in contiguous way

1 Like

[quote=“venediklee”, post:3, topic: 942653]
According to this post , “all” you need to do is define the sorting layers in contiguous way
[/quote]
Yep, found out about that today after reading through all of AlexVillalba’s blogs. Awesome stuff!
Although even when you set up all of this correctly and only use one SortingLayer config for all your Light2D’s, they are still not batched and every single small light gets its own draw call.
https://discussions.unity.com/t/922877

This means we have to use them really sparingly and replace them with HDR SpriteRenderers whereever possible. I really want to use Light2D though :frowning:

Thank you both for the insight, this is very helpful. So am I understand that this is part of the problem?

9874890--1423839--upload_2024-6-5_10-50-24.png

If I move the Ship and Props layers to be adjacent to PlatformsBack, and maybe remove the Default layer, I would see more efficient light rendering calls?

This still doesn't solve the batching problem, but right now I'll take any win I can get!

Edit: It looks like that helped. Thanks all. Now we just need to get an answer on batching

1 Like

[quote=“leohilbert”, post:4, topic: 942653]
Yep, found out about that today after reading through all of AlexVillalba’s blogs. Awesome stuff!
Although even when you set up all of this correctly and only use one SortingLayer config for all your Light2D’s, they are still not batched and every single small light gets its own draw call.
https://discussions.unity.com/t/922877

This means we have to use them really sparingly and replace them with HDR SpriteRenderers whereever possible. I really want to use Light2D though :frowning:
[/quote]
If the lights do not have same parameters(I dont exactly know which ones), they cant be batched as far as I know. Correct me if I am wrong please

Exactly, so from my testing yesterday there are 2 things you want to keep in mind when choosing your Light's SortingLayers.

1. avoid "gaps" in your affected TargetSortingLayer configuration (like you already did now)
If I have 4 Lights all targeting my adjacent SortingLayers Layer1, Layer2, Layer3, Layer4 I get 4 draw calls (one for each light).
If I now exclude Layer3 aka configure all the Lights to Layer1, Layer2, Layer4, I get 8 draw calls (two for each light)!
4 drawcalls to build the LightTexture for Layer 1&2
4 drawcalls to build the LightTextrure for Layer 4

2. try to minimize different Light TargetSortingLayer combinations in your Scene
Lets take my "all lights to Layer1,2,3,4" example again (4 draw calls).
If I exclude Layer4 from ONE of my 4 lights, I get 3 more draw calls.
3 drawcalls to build the LightTexture for Layer 1,2,3,4 (all lights expect the one i excluded Layer4 in)
4 drawcalls to build the LightTexture for Layer 1,2,3 (all the lights)

Now lets put both of these two together and create the worst case scenario:
Lets take my "all lights to Layer1,2,3,4" example again (4 draw calls).
Now I'm excluding Layer*3* from ONE light. That way I have a gap in my configuration and multiple light configurations in my scene.
I now have 11 draw calls:
4 drawcalls to build the LightTexture for Layer 1,2 (all the lights)
4 drawcalls to build the LightTexture for Layer 4 (all the lights)
3 drawcalls to build the LightTexture for Layer 1,2,3 (all the lights except the one i excluded Layer3 in)

As you can imagine this scales really well when you have a scene with lets say 15 lights.
Changing the SortingLayer config of 1 of these Lights can create up to 29 additional draw calls.

You can also get a great representation of whats happening in the Frame Debugger (Window > Analysis > Frame Debugger). Extremely useful for this kind of stuff


True, but even if all Lights are configured exactly the same way, they are not batched. We are using them for small candle lights and every small flame gets its own draw-call, even when they are in "Sprite" mode with identical configuration.

1 Like

Thanks a lot for the detailed analysis leo


Oh I didn't realize this, I tested it and it indeed looks like exact same 2d lights(even when static) do not get batched together. Maybe someone else will enlighten us