# Updates to lighting in three.js r155

**URL:** <https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733>\
**Category:** Discussion\
**Tags:** lighting, webgl-renderer\
**Created:** [July 11, 2023, 1:59pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733 "2023-07-11T13:59:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [July 11, 2023, 1:59pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/1 "2023-07-11T13:59:05Z")

</div>

The upcoming release `r155` will contain a major change in context of lighting. The legacy lighting mode will be disabled by default which affects all light intensities and how point and spot lights decay.

* * *

## What does that mean for me?

The release changes the default of `WebGLRenderer.useLegacyLights` from `true` to `false` and also deprecates the property. Meaning it will be eventually removed from the engine with `r165`.

Setting `WebGLRenderer.useLegacyLights` to `false` is one important prerequisite for achieving physically correct lighting in apps.

Disabling legacy lighting mode has two effects:

- Light intensities are not internally scaled by factor `PI` anymore. This so called _artist-friendly light intensity scaling factor_ was in place to make it easier to achieve good looking lighting with intensities around `1`. However, in context of physically correct lighting such scaling factors are incorrect and make it impossible to use proper SI units.
- Point and spot lights now decay in physically correct ways.

If you are not already disabling the legacy lighting mode in your app, you will have to update light intensities when upgrading to `r155`.

* * *

## Migrating

If you can’t effort a migration now, you can simply set the value of `WebGLRenderer.useLegacyLights` back to `true`. Since the property is going to be removed in the future, you should consider to update the lighting in the next months.

The intensities for ambient, hemisphere, directional lights and light maps can be restored by multiplying `PI` with the existing light intensity values.

The intensity of point and spot lights is measured in candela (cd) now which usually requires much higher intensity values than before. Restoring their decay to the previous behavior isn’t possible because of different computations in the shader. So scenes with point and spot light will look slightly different with `r155` even with updated light intensities.

It’s important to understand that using the new lighting mode is _just one_ prerequisite for physically correct lighting. You also have to:

- apply a real-world scale to your scene (meaning 1 world unit = 1 meter).
- not change the default `decay` values of `2` for all spot and point lights in your scene.

Only then you can actually consider SI units for point, spot and area lights. Ambient and hemisphere lights (which are special kind of lights and essentially simplified models of light probes) as well as directional lights do not use SI units.

* * *

## Motivation

The goal of this change is to provide a single lighting mode that supports physically correct lighting. We believe the engine’s lighting should have been implemented like this in the first place meaning without internal scaling factors or custom decay implementations.

Besides, `WebGPURenderer` will only come with a single (physically correct) lighting mode. We are convinced it’s better to make this change in `WebGLRenderer` now so a switch to WebGPU will become easier.

* * *

## Questions

For general questions, please reply to this thread. If you would like help updating some existing code, consider starting a new thread with the full context, then including a link in this thread.

We also recommend to check how the [official examples](https://threejs.org/examples/) and the [manual](https://threejs.org/manual/) will be updated to get a better impression of the migration tasks. You can do that by simply comparing the example code between `r155` and `154`.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [July 11, 2023, 2:02pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/2 "2023-07-11T14:02:11Z")

</div>

Pinned globally on July 11, 2023, 2:02pm UTC



---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [July 11, 2023, 2:05pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/3 "2023-07-11T14:05:38Z")

</div>

Everyone who wants a sneak preview here are the examples from the `dev` branch which are already migrated to the new lighting: [three.js examples](https://rawcdn.githack.com/mrdoob/three.js/a05dee742ccbbba8d8f8386bca2fc537d3d45727/examples/index.html)

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [July 11, 2023, 2:14pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/4 "2023-07-11T14:14:27Z")

</div>

not sure i’ve found an error here but the results look completely blown out…

I’m guessing “sneak preview” is the operative term here and will take a while to update all the examples to demonstrate the benefits of this update?

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [July 11, 2023, 2:43pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/5 "2023-07-11T14:43:06Z")

</div>

Unfortunately, you get a cached version of the old build.

I’ve updated the link so it uses a commit hash which prevents caching issues. Thanks for the feedback!

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [July 11, 2023, 2:47pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/6 "2023-07-11T14:47:48Z")

</div>

right that makes sense, examples look really great now! np 🙂

---

<div class="post-metadata">

**Author:** ![Fyrestar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fyrestar/32/52793_2.png) [@Fyrestar](https://discourse.threejs.org/u/Fyrestar)\
**Post date:** [July 11, 2023, 2:55pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/7 "2023-07-11T14:55:55Z")

</div>

> [@Mugen87](#):
>
> It’s important to understand that using the new lighting mode is _just one_ prerequisite for physically correct lighting. You also have to:
> 
> - apply a real-world scale to your scene (meaning 1 world unit = 1 meter).

Couldn’t this be done with a scaling constant setting in the renderer? There are valid reasons to use a different world scale.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [July 11, 2023, 4:11pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/8 "2023-07-11T16:11:14Z")

</div>

If it is not possible for you to scale the scene (which would be some sort of top-level scale), then you can’t use SI values. I don’t think it’s reasonable to introduce a separate scale factor to the renderer again.

---

<div class="post-metadata">

**Author:** ![Fyrestar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fyrestar/32/52793_2.png) [@Fyrestar](https://discourse.threejs.org/u/Fyrestar)\
**Post date:** [July 11, 2023, 4:32pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/9 "2023-07-11T16:32:02Z")

</div>

I mentioned it before in another topic i guess, but Unreal Engine and afaik other engine have an option for world scale too, it would be generally useful for future as well as other usage such as for physics engines conversion of metrics etc. UE also uses 1 unit = 1 centimeter as default for instance, i assume it would be nothing more than scaling a distance value.

I’m fine with just patching it in but it would be generally nice to have the option. There are for instance apps and games required being in a generally small or large scale or both, these couldn’t use physical correct lighting out of box then.

---

<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:** [July 11, 2023, 5:00pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/10 "2023-07-11T17:00:35Z")

</div>

I am yet to understand and experience the effect of the planned changes. However, I see three things, that I personally consider advantages:

- Using SI units (for distances, for lights, etc) is a form of standardization in Three.js, making it adhere to the whole scientific world. This increases interoperability and conformance. If all 3D software decides to become compatible … the SI units are the best meeting point.

- Using SI units also makes it easier to transform Three.js programs into VR/AR, as there is no need to rescale and reposition everything. This also simplifies “reading” a program as numbers have absolute meanings, instead of being relative quantities.

- It looks likes this change will simplify the core.

Having all above said, I also:

- Understand users might have to change some of their programs.

- Users may find things that are impossible to do (e.g. with the recent changes of color encoding I have cases where I still cannot make some scenes look good with the new style, so I revert to the old style).

- I assume that it still be possible for people to use other units (e.g. 1 unit = 1mm), they only have to adjust other parameters too, although it will not be possible to completely emulate the non-physical model.

- It might be good to have some form of flexibility by coefficients, controllable by the user. For example, if the model uses f(x)=e-x², it could be made to use f(x)=eax²+b, where a=-1, b=0, but both of them can be changed by the user.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [July 11, 2023, 5:26pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/11 "2023-07-11T17:26:39Z")

</div>

> [@PavelBoytchev](#):
>
> I assume that it still be possible for people to use other units (e.g. 1 unit = 1mm), they only have to adjust other parameters too, although it will not be possible to completely emulate the non-physical model.

That’s right!

@Fyrestar Did we ever discuss the “world scale” topic at Github so far? I did not find an issue but I’m not sure. If not, it might be worth to shift this particular discussion to GitHub.

---

<div class="post-metadata">

**Author:** ![Fyrestar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fyrestar/32/52793_2.png) [@Fyrestar](https://discourse.threejs.org/u/Fyrestar)\
**Post date:** [July 11, 2023, 5:33pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/12 "2023-07-11T17:33:13Z")

</div>

I’m not sure it has been discussed a couple times over past years, mostly here i think, [like here](https://discourse.threejs.org/t/what-unit-of-distance-in-threejs/20782/12) or another recently but yes, better to discuss on Github directly.

---

<div class="post-metadata">

**Author:** ![orion\_prime](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/orion_prime/32/15785_2.png) [@orion\_prime](https://discourse.threejs.org/u/orion_prime)\
**Post date:** [July 11, 2023, 7:38pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/13 "2023-07-11T19:38:05Z")

</div>

Cool!

which examples showcases the update really obviously ? or has the intensity values been tuned so that examples from both r155 and r154 look almost same ?

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [July 11, 2023, 8:44pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/14 "2023-07-11T20:44:30Z")

</div>

> [@orion\_prime](#):
>
> or has the intensity values been tuned so that examples from both r155 and r154 look almost same ?

That one. Overall, the scenes almost look identical.

---

<div class="post-metadata">

**Author:** ![anidivr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/anidivr/32/32924_2.png) [@anidivr](https://discourse.threejs.org/u/anidivr)\
**Post date:** [July 11, 2023, 10:02pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/15 "2023-07-11T22:02:48Z")

</div>

can you not just scale the scene object?

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 14, 2023, 9:07pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/16 "2023-07-14T21:07:24Z")

</div>

Exactly, why not just set `scene.scale.multiplyScalar(100)` to eg go from cm to m?

---

<div class="post-metadata">

**Author:** ![trusktr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/trusktr/32/13726_2.png) [@trusktr](https://discourse.threejs.org/u/trusktr)\
**Post date:** [August 3, 2023, 2:05am UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/18 "2023-08-03T02:05:31Z")

</div>

No, because that changes the size of the scene in the 3D world, but not the world itself, due to a `Scene` being merely a top-level node in the transform graph (any transform you apply to it is currently equivalent to the same transform as if it were an `Object3D`). It could be possible, but would need to be implemented.

Once always-physical lights is released and well tested, _then_ it might make sense to think about adding options (if maintainers agree with the added complexity), f.e. changing the SI units to other units, f.e. cm instead of m for distances, or alternative light intensity/power units, etc.

One step at a time.

In the meantime you have to convert units yourself.

```javascript
// this 1000cm value will be converted to 10m for the engine
mesh.position.x = cmToM(1000)

```

where `cmToM` is your own helper.

---

<div class="post-metadata">

**Author:** ![den-antares](https://avatars.discourse-cdn.com/v4/letter/d/b782af/32.png) [@den-antares](https://discourse.threejs.org/u/den-antares)\
**Post date:** [August 8, 2023, 9:23pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/19 "2023-08-08T21:23:44Z")

</div>

I’m trying to work out how to convert ambient and directional lights to work in r155. I haven’t started on the directional lights, but here’s what I’ve found with the ambient lights:

With an ambient light with color = 0x666666, intensity = 1, and several MeshStandardMaterials:

```javascript
Material Name | Material RGB | Rendered RGB (r149) | Rendered RGB (r155)
Red | 1, 0, 0 | 0x660000 | 0x3a0000
Gray | 0.5, 0.5, 0.5 | 0x333333 | 0x282828
Black | 0.1, 0.1, 0.1 | 0x0a0a0a | 0x0e0e0e

```

So the change must be more than a simple multiplication by pi. Bright colors are darker in r155, and dark colors are brighter. What else changed?

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [August 8, 2023, 9:55pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/20 "2023-08-08T21:55:31Z")

</div>

PCL or physically correct lighting is based on the PBR (or physically based rendering) workflow, whereby the scale of the scene determines the physically correct decay of lighting, so you’re correct, for instance, if your scene is 4000 meters wide, a multiplication by pi would not make much of a difference to the lighting effects…

---

<div class="post-metadata">

**Author:** ![den-antares](https://avatars.discourse-cdn.com/v4/letter/d/b782af/32.png) [@den-antares](https://discourse.threejs.org/u/den-antares)\
**Post date:** [August 8, 2023, 10:00pm UTC](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733/21 "2023-08-08T22:00:37Z")

</div>

The colors are exactly the same in different regions of my scene. Large objects, small obects, near objects, distant objects, they all render exactly the same RGB value (when the only light in the scene is an ambient light).

[Next page](https://discourse.threejs.org/t/updates-to-lighting-in-three-js-r155/53733.md?page=2)
