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 <pragma37@gmail.com>
Pull Request: https://projects.blender.org/blender/blender/pulls/141981
This commit is contained in:
Germano Cavalcante
2025-07-24 16:24:19 +02:00
committed by Miguel Pozo
parent 4f372d64d4
commit cb51fc5471
6 changed files with 17 additions and 4 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 = {};

View File

@@ -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. */

View File

@@ -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
{

View File

@@ -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) {