-
-
Notifications
You must be signed in to change notification settings - Fork 21.2k
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
GLES3 - Depth sorting problem with overlapping transparent textures #43253
Comments
Do you mind uploading the MRP as a zip file? You can just drag and drop it into the comment. The link you provided has enough sketchy popups that I am uncomfortable downloading from it. |
Done. Didn't see those due to my overpowered adblock. |
Depth_sorting_issue.zip |
Can confirm, same thing happens on my system using Godot 3.2.3 Also tested it on a Windows 10 system for good measure, same thing happens. |
Related to #36669. |
Happens on Mesa Intel UHD Graphics 630 as well so it probably isn't a nVidia related issue. |
The problem is related to the direction of the DirectionalLight and is limited to (caused by?) DirectionalLights. The renderer apparently orders by light direction instead of camera direction.
Godot 3.3.2 |
More specifically, it is the shadows. It always impacts DirectionalLight, and it temporarily* affects OmniLight and SpotLight. DL Shadow on/off and light angle determines if it occludes properly. With DL, none of these things have any effect:
Reducing DirectionalShadow Max Distance does occlude properly if the distance is set lower than the distance between the camera and the far tree. e.g. 2. Then as you move the camera closer and farther, the back one will overlap or not depending on the distance. When overlapping, you can move the closer tree and it makes no difference. It only depends upon the camera and the far tree distance. *Temporary effect
|
Alpha hashing, alpha antialiasing alpha to coverage can be implemented to improve the appearance of alpha scissor. These can likely be backported to In general, using alpha blending for vegetation will always be a difficult thing to get right due to sorting issues. |
Unfortunately most free/cheap tree assets or tutorials use alpha scissor or alpha blending for leaves. |
@Calinou If we couldn't handle "difficult", we wouldn't have chosen to develop in 3D. I appreciate the workarounds, however I'm interested in fixing this bug so I don't have a shoddy looking game. Other engines have beautiful alpha. Godot also has it with 2/3rds of the light types, and 50% of the directional light. I'm convinced it's a simple bug, though finding it is quite challenging as I'm out of my element in the rendering pipeline. Here's what I've found so far. After this line: godot/drivers/gles3/rasterizer_scene_gles3.cpp Line 4565 in f4e3701
I wrote a function to print out the alpha render_list (last 3 indices of elements). I also print out If DL shadow is disabled, the depth of the trees change, and so the renderlist gets sorted with the farthest away rendered first. I see values like 4-12 as I move the camera. If DL shadow is enabled, the render list is always green then red, with the light behind the red. The depth of the objects always reports the same negative values. green tree: (-7.72), red tree: (-11.24)! So that explains why it's sorting wrong half of the time. The depth value doesn't update. Now why that is, I'm still searching for the cause. I'd appreciate help on this. |
Looks like a problem in VisualServer, not the rasterizer. The scene objects already have their distance set (wrong or right) when the visual server calls the rasterizer and passes along the objects in godot/servers/visual/visual_server_scene.cpp Line 2189 in f4e3701
Edit: Since the problem is not in the renderer or OpenGL, I should be able to track it down in the next day or two. |
In godot/servers/visual/visual_server_scene.cpp Line 2015 in f4e3701
Directional Lights godot/servers/visual/visual_server_scene.cpp Line 2068 in f4e3701
The distance to the camera is never recalculated. Instead, the wrong information is passed to the renderer, which sorts incorrectly depending on angle. OpenGL or other functions in the renderer may be correcting depth sort order for opaque objects, I haven't tested, but it does not do so for alpha objects, which are sorted based upon the information from the visual server. Omni Lights What makes omnis work is that they only update the shadows if the shadows are marked dirty. So the instance depth is wrong for one frame, then corrected every frame after until the shadows are recalculated. If I tell Omnis to recalculate every frame like DLs, depth is sorted incorrectly as well. godot/servers/visual/visual_server_scene.cpp Line 2165 in f4e3701
So I see four possible solutions:
1 seems the easiest and least intrusive. I have implemented it and so far everything works. Is this the best solution? I'll write up a PR for review. Here the camera is facing towards the directional light, with shadows enabled. Front trees properly occlude back trees. Opaque house, terrain, and trunks are properly occluded everywhere, and quality alpha without using alpha scissors anywhere (which also works as any normal opaque object). Omnilights and spotlights also work better as they never occlude improperly (Image from my game, see my profile.) |
No longer a problem. See below. |
@tinmanjuggernaut
Indeed, the rendering pipeline only does per-object depth sorting. Per-vertex or per-pixel are leagues more complex and usually require some form of Order Independent Transparency (which comes with its own issues and limitations).
I agree, please make a PR so myself and others can review. :) Great work by the way! |
Unlike alpha-scissoring, this is an acceptable tradeoff.
Thanks! I'm very happy with the results. This bug has been one of the worst problems with the renderer forever. |
I was working off of 3.3. Apparently, there was a lot of work done in the 3.x branch on the VisualServer and/or renderer. This branch with my patch now occludes even the overlapping trees shown above! |
Fixed by #50721. |
Issue description:
Hi, I'm using Godot 3.2.3, GLES3 and I noticed that when you have multiple models with materials marked as Transparent and you add to the scene a source of light that can cast shadows, this will happen: https://youtu.be/2uhuNK9D7mg . As you can see, those leaves that are further away from the camera start to appear in front of the closer ones. I colored them red so it's really obvious. This only happens when there are multiple transparent objects with opaque pre-pass enabled and they are lit using a light source that casts shadows. The "Do not receive shadows" flag doesn't make a difference though. This issue is present on version 3.2.2 as well. When using the GLES2 renderer it behaves in the opposite way, rendering farther objects in front of closer ones when the depth draw mode is set to Opaque only.
Godot version:
3.2.3-stable
OS/device including version:
GPU: nVidia GeForce 1650 Mobile with nvidia-driver-450.80.02-0ubuntu0.20.04.2 driver
CPU: Intel core i5 9300H
OS: Linux Mint 20
Steps to reproduce:
Set up a scene with multiple overlapping objects which are configured as follows:
-Transparent flag enabled
-Depth draw set to Opaque pre-pass
-No alpha scissoring
Then add a directional light and enable shadows.
Example project:
Depth_sorting_issue.zip
The text was updated successfully, but these errors were encountered: