# Talk to me about point lights and performance

**URL:** <https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258>\
**Category:** Questions\
**Tags:** lighting\
**Created:** [February 20, 2023, 6:35pm UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258 "2023-02-20T18:35:01Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![viridia](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/viridia/32/15352_2.png) [@viridia](https://discourse.threejs.org/u/viridia)\
**Post date:** [February 20, 2023, 6:35pm UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/1 "2023-02-20T18:35:02Z")

</div>

So far in my game engine I’ve been keeping things simple, with a single directional light (sunlight). However, it would be nice to have point lights for local light sources - candles, lamps, fireplaces and so on, as well as dynamic lights for spells. This is particularly important if I plan to add day/night cycles into the game.

Up to this point, though, I’ve been hesitant to introduce anything like this because I don’t know what effect it would have on overall frame rate, and that’s partly because I really don’t understand how lighting works in three.js.

Static lights - such as candles - would generally have a small radius of influence and would not overlap with other point lights (in fact I could enforce this in the level editor). This would mean that even though a scene might have dozens of individual light sources, individual shader fragments would have at most two lights: the directional sunlight and the nearest point light.

Note that when I talk about a “scene” I’m talking about something that is very dynamic: the game engine supports worlds of effectively unlimited size, with scenery loaded asynchronously in the background as you travel across the terrain. This would mean, then, that the number of lights in the scene is constantly changing.

For things like spells, I can’t guarantee that the radius of effect would never overlap with other lights, but since the game’s combat is quasi-turn-based, only one spell is cast at a time. So that means that there would be three lights per fragment at most.

Then there is the question of shadows. I imagine that rendering a shadow map for dozens of individual point lights would be horribly slow. I supposed point lights could have shadows turned off, although that would not be as nice looking.

So what I’m asking is, before I start doing a bunch of work to integrate point-lighting into the engine, can someone give me a sense of whether this is even feasible, or will it have such a huge negative impact on framerate that it’s not worth pursuing?

---

<div class="post-metadata">

**Author:** ![Fennec](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fennec/32/59265_2.png) [@Fennec](https://discourse.threejs.org/u/Fennec)\
**Post date:** [February 20, 2023, 7:34pm UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/2 "2023-02-20T19:34:39Z")

</div>

IMHO, a game engine without point lights is incomplete, for an analogy, just imagine ThreeJS without point lights.

For the performance part, I think ThreeJS is already optimized and use the best practices to get the best out of the browser, you can always tweak it here and there but then you’ll find yourself in the realm of over engineering, spending time and energy where it’s not due. Then there is the user’s responsibility, I think you should let the user decide if the integrated amount of point lights is worth the performance penalty.

The integration should be a breeze, [`PointLight`](https://threejs.org/docs/#api/en/lights/PointLight) inherit the [Object3D](https://threejs.org/docs/index.html#api/en/core/Object3D) class, also unlike [SpotLight](https://threejs.org/docs/?q=spot#api/en/lights/SpotLight) and [DirectionalLight](https://threejs.org/docs/?q=light#api/en/lights/DirectionalLight) doesn’t have a target, from my understanding your engine can already handle `Object3D` and cameras, then all you need is to add some new mechanism to handle the [LightShadow](https://threejs.org/docs/?q=shadow#api/en/lights/shadows/LightShadow) class and its camera, which is the base for:

- [PointLight **Shadow**](https://threejs.org/docs/api/en/lights/shadows/PointLightShadow.html)
- [DirectionalLight **Shadow**](https://threejs.org/docs/api/en/lights/shadows/DirectionalLightShadow.html)
- [SpotLight **Shadow**](https://threejs.org/docs/api/en/lights/shadows/SpotLightShadow.html)

---

<div class="post-metadata">

**Author:** ![PavelBoytchev](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pavelboytchev/32/38639_2.png) [@PavelBoytchev](https://discourse.threejs.org/u/PavelBoytchev)\
**Post date:** [February 20, 2023, 7:44pm UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/3 "2023-02-20T19:44:53Z")

</div>

In my city simulator I have decided to make these things configurable, so the users can choose performance or beauty. The slowest thing is a dynamic shadow (it is recalculated every frame and can push FPS down to 10). Static shadows are much faster, no shadows at all – are even fasterer (sic).

Also, I have config parameters for the number of lights, number of shadows, size of shadow maps, whether people cast shadows, etc.

If the most ugly situation (for highest performance) I have only one light (directional), always at the position of the camera and no shadows.

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [February 21, 2023, 8:32am UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/4 "2023-02-21T08:32:10Z")

</div>

From what I’ve seen some games and game engines fork three and implement a modern deferred rendering queue with clustered lighting. Otherwise I don’t think you could have more than 2-3.

For instance sougen [https://twitter.com/onirenaud/status/1605192992117379072?s=46&t=Q54DhZomyZsSv5esF8GYyw](https://twitter.com/onirenaud/status/1605192992117379072?s=46&t=Q54DhZomyZsSv5esF8GYyw)

Or playcanvas [https://twitter.com/playcanvas/status/1529108543349063681?s=46&t=Q54DhZomyZsSv5esF8GYyw](https://twitter.com/playcanvas/status/1529108543349063681?s=46&t=Q54DhZomyZsSv5esF8GYyw)

---

<div class="post-metadata">

**Author:** ![titansoftime](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/titansoftime/32/1044_2.png) [@titansoftime](https://discourse.threejs.org/u/titansoftime)\
**Post date:** [February 21, 2023, 8:31pm UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/5 "2023-02-21T20:31:14Z")

</div>

I use them where I can, but with Ambient, Directional, Hemisphere in addition, I quickly start to run into a max lights shader issue, so I keep things simpler out of necessity.

---

<div class="post-metadata">

**Author:** ![Fennec](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fennec/32/59265_2.png) [@Fennec](https://discourse.threejs.org/u/Fennec)\
**Post date:** [February 22, 2023, 1:57am UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/6 "2023-02-22T01:57:29Z")

</div>

> [@viridia](#):
>
> Static lights - such as candles - would generally have a small radius of influence and would not overlap with other point lights (in fact I could enforce this in the level editor).

Well, you are in luck! @orion_prime just published this excellent implementation of the r3f progressive shadows.

> [@"Progressive-Shadows" a vanilla js implementation of r3F AccumulativeShadows](https://discourse.threejs.org/t/progressive-shadows-a-vanilla-js-implementation-of-r3f-accumulativeshadows/48277):
>
> After many trials a vanilla three js implementation of r3f’s cool AccumulativeShadows is finally ready ! demo links [https://vis-prime.github.io/progressive-shadows/?scene=simple](https://vis-prime.github.io/progressive-shadows/?scene=simple)[https://vis-prime.github.io/progressive-shadows/?scene=rx7](https://vis-prime.github.io/progressive-shadows/?scene=rx7) github Video huge thanks to @drcmda for the help

There is also the refined [drie](https://github.com/pmndrs/drei) library, with some elegant shadow implementations for [BakeShadows](https://github.com/pmndrs/drei#bakeshadows), [ContactShadows](https://github.com/pmndrs/drei#contactshadows) and also [AccumulativeShadows](https://github.com/pmndrs/drei#accumulativeshadows), it is react specific but you can always adapt it.

---

<div class="post-metadata">

**Author:** ![viridia](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/viridia/32/15352_2.png) [@viridia](https://discourse.threejs.org/u/viridia)\
**Post date:** [March 11, 2023, 10:15pm UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/7 "2023-03-11T22:15:07Z")

</div>

I wanted to follow up with the results of my experiments. Adding a dozen or so point lights into a scene did not noticeably affect performance in my case. However, that’s only if shadows are not enabled. I tried enabling them and the scene wouldn’t render at all, gave a WebGL error about not having enough texture units (this is on a Mac M1).

I think I can get by without point-light shadows, it’s mostly the shadow from sunlight (or moonlight) that is the most visually prominent.

---

<div class="post-metadata">

**Author:** ![PavelBoytchev](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pavelboytchev/32/38639_2.png) [@PavelBoytchev](https://discourse.threejs.org/u/PavelBoytchev)\
**Post date:** [March 11, 2023, 10:28pm UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/8 "2023-03-11T22:28:03Z")

</div>

> [@viridia](#):
>
> gave a WebGL error

Does it work if you use `SpotLight` or `DirectionalLight` instead of `PointLight`?

---

<div class="post-metadata">

**Author:** ![viridia](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/viridia/32/15352_2.png) [@viridia](https://discourse.threejs.org/u/viridia)\
**Post date:** [March 12, 2023, 1:48am UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/9 "2023-03-12T01:48:24Z")

</div>

It’s not the type of light that is the issue, it’s the number of lights that have shadows enabled. DirectionalLight shadows work fine, and I’m sure PointLight shadows would work fine if I only had a small number of point lights. However, because my game supports huge worlds (dynamically loading in terrain and scenery as you move around the world) there’s no way to predict in advance how many point lights there will be.

In my test scene, I had a tavern with 8 candleholders and two fireplaces, each having a single point light. When I tried to enable shadows, OpenGL complained that there weren’t enough texture units (apparently I have 16). I’m guessing point light shadows are cube-mapped, so I’m not surprised that it needs more than one texture unit per light.

---

<div class="post-metadata">

**Author:** ![PavelBoytchev](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pavelboytchev/32/38639_2.png) [@PavelBoytchev](https://discourse.threejs.org/u/PavelBoytchev)\
**Post date:** [March 12, 2023, 5:40am UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/10 "2023-03-12T05:40:05Z")

</div>

The reason to ask the question is that point lights are implemented as emitting light in 6 directions. I’m not sure whether their shadows also require more resources. So, if you replace your point lights by spot/directional lights, this might reduce the number of used texture units and make your Mac M1 happy. This experiment is very easy to conduct.

> [@viridia](#):
>
> I think I can get by without point-light shadows, it’s mostly the shadow from sunlight (or moonlight) that is the most visually prominent.

The sunlight is a perfect candidate to be replaced by a directional light, as you only care the light casted in one direction.

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [March 12, 2023, 8:29am UTC](https://discourse.threejs.org/t/talk-to-me-about-point-lights-and-performance/48258/11 "2023-03-12T08:29:50Z")

</div>

With shadows each point light will render the full scene additional six times.

Btw in some situations you can get away with using the environment map, which is practically for free, here are 100.000 „point lights“

> <https://twitter.com/0xca0a/status/1631631520585637889?s=46&t=wv5EJPuK32MHxbjV0bW_FA>
