Turn spotlight into a drop shadow?

I am hoping to make a drop shadow for my game, to inform the player of how close to the ground they are while falling.

I’m not keen on using raycast to plop a flat plane, since it does not conform to the geometry of the environment, and is an additional raycast.

I found a texture projection script, but it seems to only project onto a specific model, and does not seem to have a falloff.

The spotlight does pretty much everything I want, except it illuminates rather than darkens. Is there something I can do to make it do the opposite?

Or if anyone has a better idea for a drop shadow, that would be great too.

A SpotLight won’t work for this because lights in three.js are additive, they can only add illumination, not subtract it. So you can’t turn a spotlight into a “darkener.”

A better solution is to use a blob shadow with multiplicative blending. Create a circular gradient texture (black center → transparent edge), put it on a plane using MeshBasicMaterial, enable transparent: true, and set blending: THREE.MultiplyBlending. Multiply blending darkens whatever is underneath, which gives you a proper shadow effect with falloff.

You can position the plane just above the ground and scale it based on the player’s height while falling. This avoids extra raycasts, is very cheap, and is how most real-time games implement drop shadows.

If you need it to conform to uneven terrain, you can project it using THREE.DecalGeometry, but in most cases the simple multiplied quad works perfectly and is much cheaper.

1 Like

What I meant by falloff is how the shadow lightens the further away the original object is from the ground. Beyond the falloff distance, the blob shadow shouldn’t show up at all.

My game is uneven terrain with a cityscape. A flat plane for the blob shadow won’t be enough.

Seems I’ll be stuck with shooting a raycast regardless, or at the very least extending an existing one. I’ll take a look at decal geometry, although doesn’t sound like it is going to be too different from the material projector I linked.

SpotLight can project texture: three.js examples

Even if the texture is pure black?

I dont know. Look this topic: Fastest/most efficient way to render a simple round (non-penetrating) drop shadow under a Mesh? - #11 by prisoner849

Use negative light (i.e. white light with negative intensity). This will darken.

https://codepen.io/boytchev/full/YPGXyVo

image

9 Likes

This is not quite correct, as Pavel has demonstrated you can set a negative value to any light for it to perform negatively…

2 Likes

Thank you! Definitely not how I expected the light’s intensity value to work, but happy nonetheless.

1 Like

You’ve got two different answers there because technically both approaches can work, but they behave very differently.

Using negative intensity on a SpotLight can darken things, as shown in the CodePen example. However, it is kind of a hack and can produce odd results depending on your lighting setup and materials. Since three.js lights are designed to be additive, you may run into inconsistencies, especially if you later tweak tone mapping or add more lights.

The blob shadow approach with a circular gradient texture and MultiplyBlending is generally the more standard game solution. It is cheap, predictable, and gives you a nice falloff. Scaling it based on player height is straightforward, and visually it reads well for gameplay purposes. Most games use some variation of this instead of real shadow maps for characters.

If you just need a gameplay indicator for distance to ground, I would go with the multiplied quad. It is simpler, more controllable, and less likely to cause lighting side effects later.

Texturing the ground will also provide a helpful visual cue.