+1 vote

I'm attempting to implement a player line of sight system using light2d and light occluders. The intended effect is for it to function like a standard roguelike line of sight or that found in games like Monaco, and should support lighting from other sources.

I've changed the z-level (relative and not) of the occluders to no effect, along with exploring light2d modes. Mask has produced the result below in combination with clockwise shadow culling on the occluders:

enter image description here

The two wall tiles immediately up from the player are rendered correctly, however they are casting shadows on the other tiles in the scene, which should not be happening. Adding another sprite on top will not work either, as the only wall tiles that should be rendered are those that can be raytraced to the player.

I've searched a bit and can't find any solutions other than possibly raycasting to generate triangles/polygons for line of sight on to a separate viewport and using that as a masking texture on the active viewport - which seems like too much of a hack workaround and I'd probably just write something in nativescript at that point, but I'd like to avoid that.

Has anyone gotten anything like this to work, or have any ideas?

in Engine by (13 points)

I've added what I believe is an exhaustive answer to a slightly older question I believe this question duplicates: https://godotengine.org/qa/23818/how-can-make-tilemap-walls-with-occluder-show-and-cast-shadows?show=81284#a81284

The short answer is that I don't believe it is possible without writing your own tile-aware visibility code, but you can integrate the results with the engine 2D light system by dynamically placing occluders to reflect current visibility.

2 Answers

0 votes

I believe you merely need to specify an incomplete path for the occluder and swap the winding order. The window order matters for light OccluderPolygon2D and will determine if the light passes through the first set of edges.

by (50 points)

I believe the OP has already done that -- the tiles in the screenshot are not self-shadowing, but rather shadowing adjacent tiles. It would be possible place incomplete occluder polygons only at the "backs" of the wall tiles (e.g., line segments), but the "back" depends on the position of the player/light, and so can't be done statically without specifically designing levels and tilesets with this in mind.

0 votes

So, I was finally able to make it work. All I did was to set the LightOccluder2D into a different Light Mask than the Light2D.

by (29 points)

Changing the visible node light mask to be exclusive of the light shadow mask prevents any shadows from casting on the visible node. Without additional dynamic behavior this leaves all walls visible, which doesn't seem to be at least what the OP wanted.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.