-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
depth_draw_never
moves objects into the transparent pipeline for no reason
#73158
Comments
Looks like it works if you change render priority and then run the project or reload the editor. The issue is that the mesh isn't updating its surface cache when render priority changes. Should be an easy fix |
Also, to add to this. Nothing relevant to this issue has changed between 3.5 and 4.1. Disabling depth test or force disabling depth write always moved the object to the transparent pass (which is why render_priority worked for those objects. render_priority only applies to objects in the transparent pipeline). |
That's not my experience. In 3.5, render_priority consistently affects opaque objects as well as transparent ones, and I have recreated the setup in 3.5.1 to demonstrate these subtle differences: The opaque objects have been duplicated and colored red. Because the object named default_red perfectly overlaps with the original, render priority determines which of them is shown. Likewise, the object named depth_draw_never_red always renders on top of the original, unless you change the render_priority. Let me know if you can reproduce these results |
It doesn't make sense to me for these depth settings by themselves to affect when the object is rendered, or at least to give the user next to no choice on that. I can make a proposal about this if that is more appropriate |
My above statement was a little too strong. I'll take a look at your 3.x MRP and see if the same effect can be done in current master (with #73263 merged) Edit: I looked at your 3.x MRP and I can confirm it looks like in 3.x |
There were two pieces to this bug report:
Only the first was fixed, so reopening and renaming to track the second edit: marking as 4.1 as the changes won't be trivial. Basically, right now this block ensures that depth_draw_never always goes through the transparent pipeline: godot/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp Lines 3449 to 3460 in 8c7b98d
We could change it to:
But we run into another issue, Opaque objects are always added to the depth pass: godot/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp Lines 1041 to 1043 in 8c7b98d
We could remove that, but we would risk breaking other areas. So this change needs to be discussed after 4.0 releases and then made for 4.1 if other rendering contributors agree that it is necessary |
depth_draw_never
moves objects into the transparent pipeline for no reason
I ran into this while experimentally trying to implement godotengine/godot-proposals#1298. I tried implementing a simple silhouette material by setting the depth function to In this screenshot, there are red artifacts over the green material due to the red silhouette material being drawn in the transparent pass, while the green material is opaque. (The "Depth Function" is the property I added, it merely sets the depth comparison operator.) Such a silhouette material would rely on the fact that it would be drawn in the opaque pass, but it also should not write depth, as doing so would cause other rendering artifacts.
But I think the bigger breaking change would just be that people might already be relying on As an aside - the behavior of the materials I was testing with seems to differ a bit between the Forward+ and Mobile render modes. Not sure if there's a related issue there. |
Currently in Godot 4.0
We may have to do that, but I hope to avoid doing that if possible. We will have to discuss with other interested parties what the best solution is.
There might be. Also keep in mind that the Mobile renderer never uses a depth prepass which may break some assumptions about what information is available when. |
I tried implementing the changes suggested in #73158 (comment). My final changes can be found here: apples@451b04a. No GLES3 yet. I have not made any changes to the shadow flag in my commit, but I do believe the shadow flag should be moved as well. One additional change I had to make was changing this check: godot/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp Lines 1003 to 1005 in 61d2c85
To this: if (!force_alpha && (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
rl->add_element(surf);
} That change was only necessary in the Forward+ renderer, the Mobile renderer check was already similar to mine. I assume this is related to the depth prepass. Additionally, I had to modify this check: godot/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp Line 3459 in 61d2c85
As such: if (has_alpha || has_read_screen_alpha) { Overall, I personally think these changes would match my expectations of how materials should be assigned to the different rendering passes. Essentially, I find it odd that there are various rules for how materials are considered "transparent", when there is an explicit flag for it on the material. I feel like only materials with the However, these changes really seem to me like it would be an annoyance to people who have already made materials under these assumptions. For my purposes, I would be fine with adding a Adding a new property like this would make the rendering logic more complicated. Also, I haven't tested how these changes might interact with sky/fog/etc. EDIT: Just to add: My motivation in implementing these changes, is to create a better "character behind wall" silhouette shader in the opaque pass. For me, another viable solution would be to simply add a |
@apples The changes seem good except the removal of the check for DEPTH_TEST_DISABLED |
I realize now that I can just use a render priority of -1 to make it appear behind 💀 |
Noting here that I ran into confusing behavior with It worked after adding When I reported this on the forum here, @Calinou suggested that it may be related, so I'm putting this here in case it's of relevance to anyone working on this issue: https://forum.godotengine.org/t/depth-draw-opaque-not-working-as-expected-depth-is-not-drawn-even-when-alpha-is-1/59492 |
Godot version
v4.0.rc1.official [8843d9a]
System information
Windows 11, Vulkan
Issue description
Disabling depth testing or disabling depth drawing unexpectedly removes objects from the opaque pass, so they disappear from screen textures. This is problematic because the user may intend to keep the objects opaque. The user may also wish to write directly to the depth buffer at any time, this is why depth settings and transparency should be decoupled.
Example:
In Godot 3.5 I am able to create this x-ray effect entirely in the opaque pipeline by utilizing render priority and
render_mode depth_draw_never
in my shader, this is not possible anymoreSteps to reproduce
MeshInstance3D
and assign a meshStandardMaterial3D
depth_draw_mode = disabled
, or setno_depth_test = true
In the reproduction you'll find 3 objects corresponding to each setting, and a box for peeking at the screen texture. If something doesn't appear in the screen texture, that implies it is not in the opaque pipeline
Minimal reproduction project
issue-reproduction.zip
The text was updated successfully, but these errors were encountered: