Quick answer: Light2D shadows need explicit Occlusion Polygons per tile in the TileSet editor. Collision shapes are not used. Add an Occlusion Layer to the TileSet, draw polygons on each wall tile, enable shadow_enabled on the Light2D.

Here is how to fix Godot 4 Light2Ds that illuminate the scene but cast no shadows from your TileMap walls. The light is real, the wall is solid, the player can’t walk through it — but the light shines straight through. Light2D uses a separate occluder system from collisions, and TileMap tiles need explicit occluder polygons.

The Symptom

A Light2D with shadow_enabled = true creates dynamic shadows from LightOccluder2D nodes you placed manually, but TileMap walls cast no shadow. The light passes through walls regardless of texture.

What Causes This

No Occlusion Layer in TileSet. The TileSet asset must have at least one Occlusion Layer added before tiles can have occluder polygons.

Polygons not drawn. Adding the layer enables drawing; you still need to actually draw a polygon on each wall tile.

Wrong layer mask. Light2D’s Range Layer Min/Max determines which occluder layers it sees. Mismatched layers means the light ignores those occluders.

shadow_enabled off. The Light2D’s shadow needs explicit enable.

The Fix

Step 1: Add an Occlusion Layer to the TileSet. Open the TileSet asset. In the right panel, find Occlusion Layers. Click the + to add one. Set its Light Mask to the value you want (default 1).

Step 2: Draw polygons on each wall tile. Select a wall tile in the TileSet editor. Switch to the Occlusion Layer tab. Draw a polygon matching the visible silhouette. Repeat for each wall variation.

Step 3: Enable shadows on Light2D.

extends PointLight2D

func _ready():
    shadow_enabled = true
    shadow_color = Color(0, 0, 0, 0.7)
    shadow_filter = Light2D.SHADOW_FILTER_PCF5
    range_layer_min = 0
    range_layer_max = 0
    range_z_min = -1024
    range_z_max = 1024

Step 4: Match shadow item cull mask. The Light2D’s Shadow Item Cull Mask must include the bit corresponding to the TileMap’s Light Mask. Defaults usually match, but custom configurations require alignment.

Step 5: Verify in Scene view. Move the Light2D around. Walls should cast shadows that follow the light source. If shadows still do not appear, double-check the Occlusion Layer was added before drawing polygons (drawing without a layer added does nothing).

Per-Tile Variations

Different tiles can use different occluder polygons. A diagonal wall tile gets a triangular polygon; a half-wall gets a smaller rectangle. Match each tile’s actual silhouette for accurate shadows.

Animated Tiles

Animated tiles can change their visible art per frame. The occluder polygon stays static. For doors that visually open, also call tile_set_cell with a non-occluder version when the door opens, or animate the alternative tile.

“Light2D needs occluder polygons in the TileSet. Collisions do not double as occluders. Draw the silhouette per tile.”

Related Issues

For TileMap Y-sort, see TileMap Y-Sort. For collision shape disable, see CollisionShape Disabled.

Add Occlusion Layer. Draw polygons. shadow_enabled = true. Walls block light.