Per-object lights

I’m rendering a spaceship orbiting a planet. Because the planet is a million times larger than the ship, a shadowmap large enough to encompass the planet obviously won’t work on the ship, and vice versa.

One approach would be to light the planet and the ship differently - that is, there would be two different “suns”. The sun used to illuminate the surface of the planet would not have a shadow map. The sun used to illuminate the ship would be a small directional light placed near the ship, with a shadow map only a few dozen meters in size.

Is it possible to do something like this in three.js? (Other than, say, completely re-implementing lighting in a custom shader, which may be beyond my level of skill.)

i would want to chat with kenny, he’s building hello-worlds atm. they’re active all day talking about it on discord, too. i think he’s making this an open world api or sandbox from how it looks in the docs.

What would be ideal, although I have no idea how difficult it would be, is if lights could use the existing layer masks feature - that is, you could set a layer mask on any given light, and it would mean that the light would only illuminate objects in that layer.

Although, I suppose to be completely generalized you’d need two masks: one to indicate which objects can cast shadows on that light source, and another to indicate which objects are to be illuminated.

So in my original example, the when the ship orbiting the planet is rendered, a small direction light with a small shadow map (just large enough to encompass the ship) would be placed near the ship, and both the planet and the ship would cast shadows onto that light’s shadow map. In other words, the ship can self-shadow, and the planet occludes the sunlight when the ship goes behind the planet.

The ship doesn’t cast a shadow onto the planet, since the area of the planet is too big for a high-resolution shadow map. But the planet might accept shadows from the moon (solar eclipse), which only requires a relatively low resolution shadow map - one where each pixel of the shadow map covers hundreds of square kilometers of terrain.

I don’t think you can have per-object lights in THREE.

I did exactly that for per-pixel Lambertian illumination:

Extendable shader material with customizable lights and shadows

1 Like

That looks great, I will definitely check it out!

Real selective lighting will be possible with WebGPURenderer.

Demo: three.js - WebGPU - Selective Lights

You need Chrome Canary with enabled WebGPU flag to check out the example.

In WebGLRenderer you can try to use multiple scenes to achieve something similar (see https://github.com/mrdoob/three.js/issues/5180#issuecomment-54812294).

1 Like

Sounds like I’m not the only one who is interested in this use case :slight_smile:

I’m avoiding playing around with WebGPU until it is in the hands of regular (non-technical) users.