From cb51fc54713fed094914745684b91b6d2b2cb883 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Thu, 24 Jul 2025 16:24:19 +0200 Subject: [PATCH] Fix #141741: Combed particles are affected by occlusion of other particles Caused by 7688677e29, which replaced `DRW_draw_depth_object` with `DRW_draw_depth_loop`. `DRW_draw_depth_object` simply rendered the object without actually using the DRW manager capabilities. Now, with `DRW_draw_depth_loop`, the depth is rendered based on what the engine sees with overlays disabled, which doesn't hide the particles. The solution to this issue is to skip particle rendering in the overlay engine in `DRW_draw_depth_loop`. Co-authored-by: Miguel Pozo Pull Request: https://projects.blender.org/blender/blender/pulls/141981 --- source/blender/draw/engines/overlay/overlay_instance.cc | 1 + source/blender/draw/engines/overlay/overlay_particle.hh | 2 +- source/blender/draw/engines/overlay/overlay_prepass.hh | 4 ++++ source/blender/draw/engines/overlay/overlay_private.hh | 2 ++ source/blender/draw/intern/DRW_render.hh | 3 ++- source/blender/draw/intern/draw_context.cc | 9 +++++++-- 6 files changed, 17 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_instance.cc b/source/blender/draw/engines/overlay/overlay_instance.cc index c9363f56df9..eaa9f7df301 100644 --- a/source/blender/draw/engines/overlay/overlay_instance.cc +++ b/source/blender/draw/engines/overlay/overlay_instance.cc @@ -42,6 +42,7 @@ void Instance::init() state.is_viewport_image_render = ctx->is_viewport_image_render(); state.is_image_render = ctx->is_image_render(); state.is_depth_only_drawing = ctx->is_depth(); + state.skip_particles = ctx->mode == DRWContext::DEPTH_ACTIVE_OBJECT; state.is_material_select = ctx->is_material_select(); state.draw_background = ctx->options.draw_background; state.show_text = false; diff --git a/source/blender/draw/engines/overlay/overlay_particle.hh b/source/blender/draw/engines/overlay/overlay_particle.hh index 0c7b76c61e6..3581c477407 100644 --- a/source/blender/draw/engines/overlay/overlay_particle.hh +++ b/source/blender/draw/engines/overlay/overlay_particle.hh @@ -43,7 +43,7 @@ class Particles : Overlay { public: void begin_sync(Resources &res, const State &state) final { - enabled_ = state.is_space_v3d(); + enabled_ = state.is_space_v3d() && !state.skip_particles; if (!enabled_) { return; diff --git a/source/blender/draw/engines/overlay/overlay_prepass.hh b/source/blender/draw/engines/overlay/overlay_prepass.hh index 1f6eb6ebafe..49e0fcf8a84 100644 --- a/source/blender/draw/engines/overlay/overlay_prepass.hh +++ b/source/blender/draw/engines/overlay/overlay_prepass.hh @@ -130,6 +130,10 @@ class Prepass : Overlay { void particle_sync(Manager &manager, const ObjectRef &ob_ref, Resources &res, const State &state) { + if (state.skip_particles) { + return; + } + Object *ob = ob_ref.object; ResourceHandleRange handle = {}; diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index 8b5bfbabf8e..260e06a99fc 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -145,6 +145,8 @@ struct State { bool is_image_render = false; /** True if rendering only to query the depth. Can be for auto-depth rotation. */ bool is_depth_only_drawing = false; + /** Skip drawing particle systems. Prevents self-occlusion issues in Particle Edit mode. */ + bool skip_particles = false; /** When drag-dropping material onto objects to assignment. */ bool is_material_select = false; /** Whether we should render the background or leave it transparent. */ diff --git a/source/blender/draw/intern/DRW_render.hh b/source/blender/draw/intern/DRW_render.hh index 4090dfd5791..cd90de47eb6 100644 --- a/source/blender/draw/intern/DRW_render.hh +++ b/source/blender/draw/intern/DRW_render.hh @@ -265,6 +265,7 @@ struct DRWContext { /** Render for depth picking (auto-depth). Runs on main thread. */ DEPTH, + DEPTH_ACTIVE_OBJECT, /** Render for F12 final render. Can run in any thread. */ RENDER, @@ -396,7 +397,7 @@ struct DRWContext { } bool is_depth() const { - return ELEM(mode, DEPTH); + return ELEM(mode, DEPTH, DEPTH_ACTIVE_OBJECT); } bool is_image_render() const { diff --git a/source/blender/draw/intern/draw_context.cc b/source/blender/draw/intern/draw_context.cc index fa7e86b3cff..a4fdf895754 100644 --- a/source/blender/draw/intern/draw_context.cc +++ b/source/blender/draw/intern/draw_context.cc @@ -841,7 +841,7 @@ void DRWContext::enable_engines(bool gpencil_engine_needed, RenderEngineType *re return; } - if (ELEM(this->mode, DRWContext::DEPTH)) { + if (ELEM(this->mode, DRWContext::DEPTH, DRWContext::DEPTH_ACTIVE_OBJECT)) { view_data.grease_pencil.set_used(gpencil_engine_needed); view_data.overlay.set_used(true); return; @@ -1789,7 +1789,12 @@ void DRW_draw_depth_loop(Depsgraph *depsgraph, { using namespace blender::draw; - DRWContext draw_ctx(DRWContext::DEPTH, depsgraph, viewport, nullptr, region, v3d); + DRWContext draw_ctx(use_only_active_object ? DRWContext::DEPTH_ACTIVE_OBJECT : DRWContext::DEPTH, + depsgraph, + viewport, + nullptr, + region, + v3d); draw_ctx.acquire_data(); draw_ctx.enable_engines(use_gpencil); draw_ctx.engines_init_and_sync([&](DupliCacheManager &duplis, ExtractionGraph &extraction) {