From 318eab55841fd32eabfe28deaf4bcbcd2c31392c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Sep 2024 12:29:02 +0200 Subject: [PATCH] Fix: #126455: Missing refraction with only emissive material When the opaque layer was populated with only emissive material, no raytracing was used for it and no feedback buffer was needed. Thus, the refraction layer had nothing to raytrace against. This fixes it by forcing the use of feedback buffer in this corner case. Pull Request: https://projects.blender.org/blender/blender/pulls/127771 --- .../draw/engines/eevee_next/eevee_pipeline.cc | 14 ++++++++++---- .../draw/engines/eevee_next/eevee_pipeline.hh | 7 ++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc index 7411529806f..a12bb07c62d 100644 --- a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc +++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc @@ -555,9 +555,14 @@ void DeferredLayer::begin_sync() this->gbuffer_pass_sync(inst_); } -void DeferredLayer::end_sync(bool is_first_pass, bool is_last_pass) +void DeferredLayer::end_sync(bool is_first_pass, + bool is_last_pass, + bool next_layer_has_transmission) { const SceneEEVEE &sce_eevee = inst_.scene->eevee; + const bool has_any_closure = closure_bits_ != 0; + /* We need the feedback output in case of refraction in the next pass (see #126455). */ + const bool is_layer_refracted = (next_layer_has_transmission && has_any_closure); const bool has_transmit_closure = (closure_bits_ & (CLOSURE_REFRACTION | CLOSURE_TRANSLUCENT)); const bool has_reflect_closure = (closure_bits_ & (CLOSURE_REFLECTION | CLOSURE_DIFFUSE)); use_raytracing_ = (has_transmit_closure || has_reflect_closure) && @@ -572,7 +577,8 @@ void DeferredLayer::end_sync(bool is_first_pass, bool is_last_pass) use_screen_reflection_ = use_raytracing_ && has_reflect_closure; use_split_radiance_ = use_raytracing_ || (use_clamp_direct_ || use_clamp_indirect_); - use_feedback_output_ = use_raytracing_ && (!is_last_pass || use_screen_reflection_); + use_feedback_output_ = (use_raytracing_ || is_layer_refracted) && + (!is_last_pass || use_screen_reflection_); { RenderBuffersInfoData &rbuf_data = inst_.render_buffers.data; @@ -890,8 +896,8 @@ void DeferredPipeline::begin_sync() void DeferredPipeline::end_sync() { - opaque_layer_.end_sync(true, refraction_layer_.is_empty()); - refraction_layer_.end_sync(opaque_layer_.is_empty(), true); + opaque_layer_.end_sync(true, refraction_layer_.is_empty(), refraction_layer_.has_transmission()); + refraction_layer_.end_sync(opaque_layer_.is_empty(), true, false); debug_pass_sync(); } diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.hh b/source/blender/draw/engines/eevee_next/eevee_pipeline.hh index 515cce87247..d2b9dc7a0a8 100644 --- a/source/blender/draw/engines/eevee_next/eevee_pipeline.hh +++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.hh @@ -303,7 +303,7 @@ class DeferredLayer : DeferredLayerBase { } void begin_sync(); - void end_sync(bool is_first_pass, bool is_last_pass); + void end_sync(bool is_first_pass, bool is_last_pass, bool next_layer_has_transmission); PassMain::Sub *prepass_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion); PassMain::Sub *material_add(::Material *blender_mat, GPUMaterial *gpumat); @@ -313,6 +313,11 @@ class DeferredLayer : DeferredLayerBase { return closure_count_ == 0; } + bool has_transmission() const + { + return closure_bits_ & CLOSURE_TRANSMISSION; + } + /* Returns the radiance buffer to feed the next layer. */ GPUTexture *render(View &main_view, View &render_view,