2D lights and shadows sample

Adding lightsources and objects casting shadows can really add to the visual appeal of a game. Tutorials and examples of this effect are fairly common (example: https://github.com/mattdesl/lwjgl-basics/wiki/2D-Pixel-Perfect-Shadows) and for Defold users @d954mas and Sayuris1 have shared their solutions here and on Discord:

We’ve taken the project from Sayuris1, made a few improvements and packaged into a reusable sample project which can be added to any Defold project in just a few steps. Here’s the sample project:

And a demo: Lights 1.0 (move with arrow keys)


(can’t load your demo in safari on both mac and iPhone)


confirming it doesn’t work on Safari

Develop > Experimental Features > WebGL 2.0 (and may be WebGPU)

1 Like

It’s cool that now there’s an example of this. It works in Firefox, but the shadows are updated with some delays and shifts. Is this intended as part of the “rude example” or is it a bug?

1 Like

I’ve updated one of the shaders. It should work now: Lights 1.0

This is caused by the size of the occluder map being too small. I’ve updated the example to pick a size more appropriate to the screen resolution.


it works now, but without shadows in Safari (Chrome is fine).

1 Like

It’s working in Safari 14.1.2 with shadows for me. FWIW I actually find the performance in Safari is better than that in Chrome.

1 Like

works for me know (I’m not sure what it was and why)
UPD: Hmm, I don’t understand what’s going on

1 Like

Amazing! Thank you!
I use it on my game. It works! I’ll read the render light config to apply on my own render later.
Two questions:

  1. Why the light stay on scene after a restart / reload (video) and how to remove it?

  1. I should create two separated tilemaps to achieve a good result (one with the material and one without). Is there any other solution? Extra tilemap will affect the performance? (this game is really simple so I don’t mind but I’d like to know it)

thank you again!

Ah, you found a bug! The lightsource.script did not remove the light when deleted. I’ve pushed a new version of the sample project that fixes this.

If you want only certain tiles to cast shadows then yes, you need two tilemaps, one with the light_occluder_tile_map.material and one without.

As with all other components each additional component you add will have an impact. But usually it’s only a small impact. You should measure it using the profiler to be sure.

Yes, maybe. The tilemap material (or rather the shader program) could perhaps be modified such that it doesn’t render tilemap layers with a certain z-value. You could create your tilemap so that layers with a z-value larger than some value will cast shadows while others won’t.


I changet 0.5 to 1 in default_size = default_size * 0.5 and now everything works fine. I don’t know why, but 0.5 is not the correct value for my display.

There are also some strange things in the scene editor. Hm…

1 Like

Yeah, it was a quick tweak to make some kind of best guess, but I think it’s better to pass a size that works for your project like this instead:

lights.init({ render_target_size = 512 })

I set render_target_size to 1368 in the example project, is that correct? This is the maximum game resolution in the project settings.

There is also a point that if you set the lighting radius of 1024 or more then there will be noticeable inaccuracies in the raycasting of black figures, they become rude. How would it be possible to adjust their accuracy higher?

It’s going to be pretty expensive to calculate lights with this kind of radius on such a massive render target.

The problem with precision of shadows is caused by a light diameter which is larger than the render target.

1 Like

Two additional articles that might help someone: