New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Graphical glitch with two directional lights and ViewportContainer (background visible with inverted colors) #44394
Comments
I'll just go out on a limb and say that this is expected behavior. Please clamp your alpha before blending. Godot is lacking a bit of functionality to make this easy but it's possible to workaround. So let me go back and explain what's going on here. Why is alpha of 2.0 bad? Well, a naive ViewportTexture shader will look like this:
By default, Godot CanvasItem shaders use a blend function of GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA The math then literally works out to 2 * SRC_COLOR - DST_COLOR, so invert what is on the screen and paint an oversaturated version of your render texture on top, which is exactly what your screenshot shows. One "fix" is simple. Edit the shader for your viewport texture and modify the shader to the following:
Clamping alpha will prevent undesired blending behavior. Oh, one thing I'll mention. Disabling HDR on your viewport texture (by setting it to RGBA_8 pixel format) should inherently clamp the alpha. I'd suggest considering that as a simple workaround. I cannot for the life of me figure out how to do this in Godot, so I'll leave it as an exercise to the reader. But basically, if the texture cannot represent alpha outside the range of 0.0 to 1.0, then you're never going to end up with an alpha of 2.0 and cause this problem in the first place. Now, this might be more performant, but this technically might not be the best looking way to fix the issue, and in fact is likely to break down when transparent objects are rendered. To have better control, Godot needs to be improved so that we can directly control the blend functions and blend equations, or it needs to internally perform mitigations to this issue when used as a ViewportTexture (as tends to be the godot way). (Also, just so you know, this is all only an issue because you have multiple directional lights. That's the only thing Godot 3.2's GLES3 renderer is unable to handle. For performance reasons, you'd do better by having the second light work be a spot or point light.) Anyway, I'll explain some of what you would do in a pure OpenGL ES program, but note that this is all moot because Godot 3.2 is already released and unlikely to completely rework blending, and Godot 4 will use Vulkan, and additionally it renders all lighting in one pass (in 3D)... though maybe this still matters in 2D or in the low end renderer: Basically, you can deal with this by using separate blend functions for the alpha channel: Is a normal OpenGL ES program, you can clamp alpha by painting a square over the screen, blending color with ZERO ONE and blending alpha with ONE ONE and blend equation GL_MIN: What I would suggest for additive lighting passes is using glBlendFuncSeparate and using alpha equation of GL_ONE GL_ZERO or GL_ZERO GL_ONE. I think for transparent objects, you might want to do something slightly different, not sure. |
I don't know the term for this specific glitch, so if someone does know please amend the title.
Possibly related: #43760
Godot version:
OS/device including version:
Issue description:
If you have a mesh in a
ViewportContainer
and two (directional?) lights, the background is visible through the mesh with inverted colors. The strength of the effect seems to depend on the angle of a face to the camera. This does not happen when using GLES2.Steps to reproduce:
Camera
with Cull Mask set to only layer 1.ViewportContainer
Viewport
as a child with Transparent Bg enabled.Camera
with Cull Mask set to only layer 2.MeshInstance
with any mesh and Layer Mask set to layer 2 (and ensure it is visible for the second camera).DirectionalLight
s. Their orientation doesn't matter.MeshInstance
with any mesh and Layer Mask set to layer 1Minimal reproduction project:
viewport_inverted_bg_color.zip
The text was updated successfully, but these errors were encountered: