How to make tiles with occluders visible?

Godot Version

4.2.2

Question

I currently have two tile maps in the scene, one for the floors and walls and such, and one for objects that are going to be on the floor. I set up an occlusion polygon in the tile editor in the tilemap for a wooden box, and it casts a shadow just fine. The problem is, the wooden box itself is also a shadow! How can I make it cast a shadow while itself still being lit up?

2 Likes

I found a solution, but I don’t like it…

I created a second PointLight2D node on the lantern that was a copy of the first one, except I changed the Item Cull Mask in the Range and Shadow to be 2 instead of one. I then created a second Occlusion layer in the TileMap that was a copy of the first one, and changed the first layer (Occlusion Layer 0) to be set to Light Mask 3, and I set the second layer (Occlusion Layer 1) to Light Mask 1. This let’s the object be lit up while still casting a shadow.

I am really hoping that this is a ‘stupid solution’ and that someone here knows a better way to do this…

2 Likes

Thank you! Using the Item Cull Mask in both the Range and Shadow is what made this finally work for me as well. In case anyone else is lost and comes across this, this is what I did:

  1. set up one light2d node and a tilemap node, and have their light cull mask and light mask be on the same layer. This is your ‘normal’ tilemap, which displays shadows how you want.
  2. set up another light2d node and a tilemap node, but have this tilemap be a copy of the first one with an occlusion layer, and set their light cull masks and light mask on the same layer (something like layer2, if for step 1 you have them on layer1). This second tilemap is solely lit up by the second light2d node, and the light2d node does not affect anything else in the scene.

Doing it this way is probably pretty tedious, but it also makes it so the ‘visible’ tiles from step 2 are always lit up, and the first tilemap occludes shadows like you want.

Update: I wanted to give an update because the original approach is very stupid. The actual simplest way to fix this is just to have a second light source which ignores the occlusion maps on the tilesets, by disabling the shadow thingy somewhere in the inspector. You don’t need to create a copy of the tilemap! Just a copy of the light, with that one property whose name i forgot, disabled.

I tried you updated method but it did not seem to work. I added a second light source (flashlight), and disabled shadows (only on the second flashlight) but now the flashlight lights up the area behind the tile

try having the flashlight on a layer separate from the ground, and let the tile be affected by that layer as well. So the flashlight would only be interacting with the tile and not the ground

I’ve been having this problem too. Supposedly godot 4.4 adds a way to fix it (CanvasItem light_mask is ignored by LightOccluder2D occluder_light_mask · Issue #64939 · godotengine/godot · GitHub) but I’m not sure what that way is. For now I might just have to use your workaround.

Having difficulties - does the copied light have the same light mask as the original? The closest I’ve come in trying to implement this has had it sort of working, but the shadows are not solid black - I’m assuming because they’re blending with the lighting from the copied, no-shadow light.