• 2D
  • Problems with Light2D and Tilemaps in a topdown game.

Hello, all. I am trying to do something really challenging with the tilemaps and the Light2D on my topdown project.

I wonder if there is a way for the Light2D to detect whenever it is in front or behind a wall. Sadly, Ysort doesn't work with 2Dlight as it does for sprites.

I've managed to get this effect by setting the wall tiles light mask to 2 and the Light2D range item cull mask to 1 and 2. The wall tiles are 32x96 and the occluder is a 32x32 square at the bottom of each tile. But this is not enough.

As you can see here, I haven't found a way to prevent the walls from getting lit on the wrong side, when the light is behind it. I could place the occluder to the top wall tile instead of the bottom, but it wouldn't make much sense geometrically. There is another problem.

Let's say that the player stands in front of the wall holding a torch, or there is a torch hanged on a wall. The light doesn't reach the floor at all and only lits as far as the wall bottom. Problems occur also if the player is behind a wall holding a torch (On my project, if the player goes behind a wall, the wall becomes transparent, but that is a headache trying to get the lights right when it happens).

So far, I understand that trying to give a 3D space features to the 2D tiles is very difficult. I wonder if there is a solution to make this work properly. My thought are:

  • Use 3D nodes for the walls and make the game 2.5D. The camera would still be fixed as topdown. I am not sure if this would work out, since I haven't experiemented with 3D yet.
  • Do a complicated system where RayCast2D detects whenever there is a wall on the down direction. When it collides with a wall tile, it adds an occluder. Not sure if this would be a good option, or how it would affect performance.

I've tried experiementing with CanvasLayers, duplicated tiles and many other things, but nothing worked.

Any ideas?

5 days later

I think it would be interesting to try changing the shadow gradient length depending on the position of the light, so if your light is above the tile, set its gradient length to zero. But it would be hard to modulate for multiple lights.

4 days later

It would be intresting to try, but I am not sure how to detect whenever the lightsource is above or below a tile, since Tilemaps behave like a single object. I wish Ysort worked with lights.

6 months later

Hello! Did you have some desidions for this issue?

I'm not the OP, but I was interested in getting some similar effects, and create a demo project for one approach to many of the same problems: https://github.com/llasram/godot-visibility-demo

Some of the details about where to place shadows can be controlled by manipulating SHADOW_VEC in a light shader. I don't have a cleaned up example of that and I don't believe there's a working example in the official demos, but discussion on godotengine/godot!32851 includes a working example with work-around for the misbehavior prompting the issue.

HTH!