I'm trying to setup a 2D game with lighting, but can't get lights to only illuminate specific objects. I've created a simple sample project with my expectation of how this should be working, and am hoping someone can see and explain what concept I'm missing here...

Full project as a .7z : https://file.io/rfpp6xGcRXTc (attribution: uses assets from the Pixel Crawler pack: https://anokolisa.itch.io/dungeon-crawler-pixel-art-asset-pack )

Scene setup:

  • Node2D (root node)
    • TileMap (Visibility.LightMask=1)
    • Sprite2D (Visibility.LightMask=1)
    • Sprite2D (Visibility.LightMask=2)
    • Sprite2D (Visibility.LightMask=3)
    • Sprite2D (Visibility.LightMask=4)
    • CanvasModulate (Color=DarkGrey(0.21,0.21,0.21,1.0); Visibility.LightMask=1)
    • DirectionalLight2D (Visibility.LightMask=2; Shadow.Enabled=True; Shadow.ItemCullMask=2)
    • Button (onPressed toggles .Enabled of the DirectionalLight2D above, on LightMask 2)
    • DirectionalLight2D (Visibility.LightMask=3; Shadow.Enabled=False)
    • Button (onPressed toggles .Enabled of the DirectionalLight2D above, on LightMask 3)
      Editor Screenshot

The idea is:

  • TileMap providing a ground background (Light Mask 1)
  • 4 Sprites on 4 different Light Mask layers
  • CanvasModulate to darken one/all Light Mask layer(s) (same behavior if this is set to a single Light Mask or all 4?)
  • 2 DirectionalLight2D s , each with a button to toggle it (light.enabled = !light.enabled), one on Light Mask 2, one on Light Mask 3

Expectation:

  • Can press buttons to toggle lights, which will each only illuminate one of the 4 sprites

Reality:

  • Either light fully illuminates all 4 sprites and the tileMap

Game Screenshot

Since this hasn't gotten any replies yet, I'll try rephrasing as a direct question:

How can I make a 2D light only affect/illuminate some sprites, leaving others in the dark?

I thought a light would only illuminate sprites with a matching Light Mask, but that doesn't work.

https://docs.godotengine.org/en/stable/tutorials/2d/2d_lights_and_shadows.html#setting-up-shadows

Occluder Light Mask: This is used in tandem with PointLight2D and DirectionalLight2D's Shadow > Item Cull Mask property to control which objects cast shadows for each light. This can be used to prevent specific objects from casting shadows.

You might want to look into the range layer max & min properties, I think(note, I don't develop 2D games, I'm just going off of what I interpret from reading the docs on this).
https://docs.godotengine.org/en/stable/classes/class_light2d.html#class-light2d-property-range-layer-max

Or you could also try using the z-index based option listed there.

    Thanks for the reply, but this appears to be a bug with DirectionalLight2D.

    In my original post/setup, on each DireactionalLight2D I was mistakenly setting the Visibility.LightMask (which controls the lights cast on a node, nonsensical for a light) not the Range.ItemCullMask (which nodes are affected by the light). Shout-out to https://www.imaginaryrobots.net/posts/2022-02-03-understanding-light2d-masks-godot/ for helping me understand that (I've also renamed all my 2D Render Layer names as suggested in that post, for clarity).

    The problem remains, though: toggling either DirectionalLight2D (with its Range.ItemCullMask set to only a single 2D Render Layer) illuminates the entire scene, not just nodes with a matching Visiblity.LightMask 2D Render Layer.

    Per Megalomaniak 's suggestions, I tried limiting this by Z Index : setting the intended sprite to have a non-Relative Z Index of 10 (leaving all the other nodes at their default 0) and then changing the DirectionalLight2D 's Range.ZMin to 9. The result is the same, the DirectionalLight2D continues to illuminate the entire scene.

    Then I tried adding a PointLight2D to the scene, with the same Range properties as one of the DirectionalLight2Ds, and with a texture scaled large enough to cover 2 of the sprites (and a portion of the background tilemap). Adding a new button to toggle this light shows that the PointLight2D correctly illuminates only the sprite with the matching Light Mask.

    new PointLight2D in editor
    Working in-game (note: the DirectionalLight2Ds still don't work in exactly the same way as shown in a screenshot in the original post):
    new PointLight2D in game

    Updated 7z archive with changes described: https://file.io/t7jIHt3MOnJO

    I'm going to try to find the right place to report a bug, and link to this thread.