Open hsandt opened 1 year ago
I bumped into this limitation too. During my web search for a workaround (which failed), I found several related posts. Posting them here to get an indication of how much demand there is, and what has been tried as workaround.
This issue is not directly related but has a minimal reproducing project that is useful for testing.
The best I could do was using mix mode, ONLY use same intensity lights, and ONLY use white and transparent in the gradient. (The transparent has to be white-transparent)
This STILL gives artifacts on the edges where lights touch (the darker lines). Likely due to anti-aliasing. Screenshot has 1 directional light from above and 2 point lights in the cave corridors.
There's also my old proposal: #891 My solution was basically not using Light2D 🤷♂️
But I really want Light2D for the shadows (maybe bump maps).
I managed to hack it in, once you find the shader code for the blending it is actually trivial to add a 'max'. Will try to make a proper PR.
I managed to hack it in, once you find the shader code for the blending it is actually trivial to add a 'max'. Will try to make a proper PR.
Thanks, I'll test it when I have some time (just finished compiling Godot editor on my new machine, it took a while but an incremental build with your PR should be fast).
By the way I noticed I never linked to this bug: https://github.com/godotengine/godot/issues/77889 which is not directly related but it is where I originally posted the MRP mentioned by bgie, and the page has more pictures to understand how my light playground works.
So I'll probably try the PR on both the mentioned MRP and the real game where I initially found the issue (which is open source: https://github.com/hsandt/flame-of-hope-godot if you want to test it yourself), where I could never set up satisfying lights due to the Mix Blend Mode bug mentioned above - but a Max would just give what I want.
Describe the project you are working on
A top-view puzzle game with various light sources in a dark place
Describe the problem or limitation you are having in your project
I'm adding light sources on the player character and torches in the level, but in Add blending mode, it stacks up very fast and it gets too bright as soon as character approaches a torch.
So I switched to Mix blending mode, which seemed to Max at first, but when one light really gets brighter than the other, a weaker light drags the final lightness down. According to the doc, this actually uses linear interpolation.
I'd like to preserve the Max lightning from all light sources. It doesn't need to be a perfect max, a smoothed curve that reduces contribution of further lights when there are more and more would also work (for instance, a logarithmic progression). As such, a custom formula blending mode where user inputs what they want or points to a custom script would also work.
And if we add Max, we may as well add Min although I don't have a particular need for it right now.
According to this thread: https://ask.godotengine.org/111101/achieving-light2d-with-blending-using-maximum-value-instead
this can be accomplished using the existing GL_MAX and GL_MIN value.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Add two Blend Modes: Min and Max.
Alternatively, a custom Blend Mode where you can write your own formula by iterating on some array of light values (more complex)
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
Max blending mode
When two light masks are intersecting the max value of all light sources is used for the final light value.
Since I discovered a bug in the Mix blend that makes blending assymmetrical in the meantime, I'm gonna use that bug to take a screenshot which coincidentally gives me the result I want in some cases:
See how 1.7 takes over 1.3 without adding extra light.
Min blending mode
Same thing, but the smallest value takes over. Again, I exploited a bug in the Mix blending mode to capture this:
Btw I'm gonna report the bug, but I can definitely not rely on it in my game since Mix will sometimes use Min, sometimes use Max depending on the order of creation of the Light2D, and at runtime the order may change again.
If this enhancement will not be used often, can it be worked around with a few lines of script?
No, I can write my own shader to grab to the max value of some combination of values but that won't be simple. I used stencil once to make custom masks but I'm not sure you can use multiple values of them.
Is there a reason why this should be core and not an add-on in the asset library?
While a custom shader could do, it's more convenient to reuse the existing Light2D node and since Blending Mode is an enum, internal code is the best place to add a new value.