How many lights should a deferred shading engine support without dropping FPS?

Weird question, I know.

I’m working on a deferred shading engine with MonoGame.
It has directional and point lights, and no shadows yet. If I create a random level with trees, rocks, bushes etc, I can have about 70 active lights before FPS goes below 60.

I’m running at 1920x1080, with GeForce GTX 1060 and i7-6700 CPU.

Now my question is - is it reasonable? Or am I doing something wrong and bleeding FPS?

A good answer would be “that depends on your game requirements” to which I’ll reply: “I want to ship it with a level editor so players can theoretically do a lot of lights, and I want it to work on laptops”.

So I need as many FPS as I can, but I’m not sure if my current performance is good and trying to optimize it will not give me much, or maybe I messed something up and I should easily have, say 300 lights at 60 fps, in which case I’ll investigate it further.

Ofc I’m not looking for an accurate answer, just your general feeling :slight_smile:

Thanks!

Well, that depend on great many variables.
For example it depends what light model you use, Schlick’s aproximation / Cook-Torrance will be considerably more expensive than Blinn-Phong. Then it depends on how many pixels get calculated, so combined lit up area, render target resolution. Of course, most of all, it depends on hardware. In my project 2d project I tried like 800 lights and it run at 600 fps. Point here being is to demonstrate how little it says without additional information.

Most important thing to get right is the bounding geometry. Unless it is extremely specific case, don’t do full screen passes, one of best advantage of deferred rendering is how easy it is to limit rasterization area for individual lights (as well as how easy it is to batch them, be it geometry merging or simply instancing).

Then it depends on how optimally packed your gbuffers are, is everything as tight as possible or do you use Vec4 to keep world position? And much more. Generally speaking, simple lights without shadows are pretty cheap, shadows is where it gets expensive (ofc in full PBR, few large lights can take some performance budget too).

Hi @Ravendarke thank you for the reply, you did give me a good answer (I need to optimize lights boundaries).

Just wondering - in your project how many FPS were actually “lost” on lighting itself? My project is 3d so I assume I’m investing more FPS in building the g-buffer. Also were your light geometries 2d or 3d? Did you use spritebatch for them?

Thanks!

No, I don’t use spritebatch. My bounding geometry is Ngon for my 2D, for 3D I use either Ngon billboard or sphere. In both cases instancing them as long as the light doesn’t need shadows. Largest performance difference between my 2d and your 3d project is caused by amount of calculated pixels, which is relatively low in my case as game is rendered in pixel art style at 1/3 of resolution, it was really just for demonstration that it is hard to say if that performance is okay or not :slight_smile:

1 Like

Why can’t you use instancing if you need shadows? O.o
I use instancing while building the gbuffer (got huge amount of objects to draw) and assumed I could use it with lights geometries too

Because you need to bind individual light’s shadow gbuffers when rendering lights, you can technically build large shadow atlas but there are few more details that makes it complicated / inefficient.

1 Like