How to achieve dynamic directional 2D lighting and shadows?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By mjtorn

Hi!

I’m trying to make a ceiling light work as expected in a 2D adventure game, but I can’t. This question would apply to platformers and the like, as long as it’s “shot along the Z axis”.

My approach so far has been to have a Light2D with a cone-shaped light texture and adding a small LightOccluder2D at the player’s feet.

Whenever I run that, two things happen. First the fan on my computer sounds like it’s about to go airborne, and second the shadow is ridiculously (infinitely?) long no matter what settings I tweak. The Light2D also lights up the entire room outside the cone-shaped texture and the LightOccluder2D casts this crazy shadow outside of it as well.

I found a tutorial for Unity3D which pretty much describes what I’m going for: a combination of normal maps and lights. We’re using Spine for animations, so let’s put that aside for now and focus on the lighting, because it seems impossible to do normal maps on Spine nodes (link to relevant part of the video).

This part of the video is what I’m looking for. How do I achieve a directed spot light?

If I should use LightOccluder2D to create a shadow, exactly which combination of settings makes the shadow not ridiculously long? Or if I’m barking up the wrong tree, could you tell me what to use for the shadows?

I’m tagging this shader as well, in case I need to use Godot’s shader language - which I’m completely unfamiliar with - to do this.

Thanks everyone and I’ll be happy to give more information if needed! Just hoping I don’t have to switch back to Unity over this.

The 2D engine in Godot has no concept of a Z axis so I don’t know how it could be replicated exactly like the video shows, unless you actually use 3D (but because it’s separate dedicated engines you don’t get the same 2D goodies). I would have thought of a light texture to fake this, however I don’t understand what’s up with the shadow. What do you mean “it’s too long”? When there is a single light, shadows it projects go on forever because there are no other light, and also because again, Godot 2D lights have no concept of depth, so it’s casted straight, not from “slightly above” or “behind” the screen plane.
There have been mentions of the concept of depth in a few Github issues but it seems nobody made such a request so far.

I investigated a little and found there is a height property on lights that seem to relate to normal maps, and Z Min and Z Max which allow to cull it for nodes beyond a given Z-order. There is also a Gradient Length parameter which seems to limit the length of the shadow, but that gradient is applied backwards to what you might want (tbh I have no idea what use case this gradient would have in its current direction… maybe it’s a bug?).

For example, here is what I get with gradient length: https://media.discordapp.net/attachments/408555922349359105/539808986858389515/unknown.png
And here is how it would look if it could be inverted: https://media.discordapp.net/attachments/408555922349359105/539809561973096459/unknown.png

Edit: I got another idea, maybe you could invert the light texture so you get a similar result?

Zylann | 2019-01-29 13:57

So that’s the long version of “Use Unity instead” :frowning:

I would have thought of a light texture to fake this, however I don’t understand what’s up with the shadow.

You mean a texture in Light2D like I did?

It’s a bit worrisome as well that the GPU sounds like it’s going to overheat with this approach.

What do you mean “it’s too long”? When there is a single light, shadows it projects go on forever because there are no other light, and also because again, Godot 2D lights have no concept of depth, so it’s casted straight, not from “slightly above” or “behind” the screen plane.

I think that answers it. By too long, “goes on forever” is what I speculated it to be, that it literally is an infinite shadow.

Culling does not appear to be a problem here, and I understood that Gradient length is a kind of offset from the LightOccluder2D.

There have been mentions of the concept of depth in a few Github issues but it seems nobody made such a request so far.

Like, no one ever wanted any kind of spotlight 2D lighting? Maybe I’ll think about how to formulate a feature request and hope someone is up for it.

In case someone has wanted this, is there maybe a shader snippet that could be copypasted into good use? :wink:

Thanks for the reply!

mjtorn | 2019-01-29 14:19

Yeah also if your GPU needs more power it’s because of shadows, these are computed with shaders instead of being done on CPU. It scales well and looks better, but can generally have a higher cost, I guess.
I think the best way to make Godot support your use case is to post a request on Github describing it, because otherwise I don’t think it will be worked on (until someone else eventually asks for it too). There are plans to revamp the 2D light system so that could enter in the list of things to improve.

Zylann | 2019-01-29 19:38

There was 11.2018 vote result on patreon.
https://www.patreon.com/posts/23510558
and there is something about it.

Roadmap Priority:

  • Directional 2D Shadows: 17.24%

not sure when it will be done though.

volzhs | 2019-01-30 05:47

I think the Light2D texture is too big, because if the light is always undirected and whatever, I could make due with a much smaller texture and increase its intensity. I’m on the road now so I can’t test properly, but it doesn’t matter, because it seems impossible to do what I need to do with this approach.

I did receive something that might be a Godot 2.1 example using the shader language. I’ll give that a shot, because I simply can’t accept that a real engine has absolutely no way of making a 2D shadow even if it requires this type of scripting.

What else needs revamping? I haven’t noticed much of problems otherwise, but obviously I haven’t used the lighting features a lot either…

Thanks!

mjtorn | 2019-01-30 07:57

Directional 2D Shadows: 17.24%

Thanks for pointing that out!

Does this automatically imply something like a SpotLight2D or similar directional light source as well? i suppose it would, but just to make sure what’s up.

And every time I’ve tried to bribe someone to implement a missing feature or enhancement to Godot, I’ve failed, but is this something where a bribe would be well received by someone? And by bribe I mean a bounty-like contract to implement it for money.

Patreon’s kinda shitty in that if I use my little money on Godot development and there’s a ~15% probability of getting what I need, I’d rather wait until I’m 700% richer and then reconsider.

mjtorn | 2019-01-30 08:01