From 7d95fed91196d5a65bb10c724e6e44c01d773282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 2 Sep 2024 19:14:01 +0200 Subject: [PATCH] Overlay-Next: In-Front support This adds the missing in-front passes submission and reorder the passes for better performance. Rel #102179 Pull Request: https://projects.blender.org/blender/blender/pulls/127020 --- .../overlay/overlay_next_antialiasing.hh | 7 ++- .../overlay/overlay_next_background.hh | 7 ++- .../draw/engines/overlay/overlay_next_grid.hh | 4 +- .../engines/overlay/overlay_next_instance.cc | 63 ++++++++++--------- .../engines/overlay/overlay_next_private.hh | 3 +- .../engines/overlay/overlay_next_shader.cc | 4 ++ .../engines/overlay/overlay_next_xray_fade.hh | 4 +- .../shaders/overlay_xray_fade_frag.glsl | 11 ++++ 8 files changed, 65 insertions(+), 38 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_next_antialiasing.hh b/source/blender/draw/engines/overlay/overlay_next_antialiasing.hh index 099209f7358..7ac91dcb3e6 100644 --- a/source/blender/draw/engines/overlay/overlay_next_antialiasing.hh +++ b/source/blender/draw/engines/overlay/overlay_next_antialiasing.hh @@ -50,6 +50,8 @@ class AntiAliasing { private: PassSimple anti_aliasing_ps_ = {"AntiAliasing"}; + GPUFrameBuffer *framebuffer_ref_ = nullptr; + public: void begin_sync(Resources &res) { @@ -63,9 +65,9 @@ class AntiAliasing { { PassSimple &pass = anti_aliasing_ps_; pass.init(); + pass.framebuffer_set(&framebuffer_ref_); pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL); pass.shader_set(res.shaders.anti_aliasing.get()); - pass.framebuffer_set(&res.overlay_output_fb); pass.bind_ubo("globalsBlock", &res.globals_buf); pass.bind_texture("depthTex", &res.depth_tx); pass.bind_texture("colorTex", &res.overlay_tx); @@ -75,8 +77,9 @@ class AntiAliasing { } } - void draw(Manager &manager) + void draw(Framebuffer &framebuffer, Manager &manager, View & /*view*/) { + framebuffer_ref_ = framebuffer; manager.submit(anti_aliasing_ps_); } }; diff --git a/source/blender/draw/engines/overlay/overlay_next_background.hh b/source/blender/draw/engines/overlay/overlay_next_background.hh index ff312219a15..3a3e2c3bdb6 100644 --- a/source/blender/draw/engines/overlay/overlay_next_background.hh +++ b/source/blender/draw/engines/overlay/overlay_next_background.hh @@ -16,6 +16,8 @@ class Background { private: PassSimple bg_ps_ = {"Background"}; + GPUFrameBuffer *framebuffer_ref_ = nullptr; + public: void begin_sync(Resources &res, const State &state) { @@ -67,7 +69,7 @@ class Background { } bg_ps_.init(); - bg_ps_.framebuffer_set(&res.overlay_output_fb); + bg_ps_.framebuffer_set(&framebuffer_ref_); /* Don't clear background for the node editor. The node editor draws the background and we * need to mask out the image from the already drawn overlay color buffer. */ if (state.space_type != SPACE_NODE) { @@ -92,8 +94,9 @@ class Background { bg_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); } - void draw(Manager &manager) + void draw(Framebuffer &framebuffer, Manager &manager, View & /*view*/) { + framebuffer_ref_ = framebuffer; manager.submit(bg_ps_); } }; diff --git a/source/blender/draw/engines/overlay/overlay_next_grid.hh b/source/blender/draw/engines/overlay/overlay_next_grid.hh index e177b9496a5..195f780f790 100644 --- a/source/blender/draw/engines/overlay/overlay_next_grid.hh +++ b/source/blender/draw/engines/overlay/overlay_next_grid.hh @@ -63,13 +63,13 @@ class Grid { } } - void draw(Resources &res, Manager &manager, View &view) + void draw(Framebuffer &framebuffer, Manager &manager, View &view) { if (!enabled_) { return; } - GPU_framebuffer_bind(res.overlay_color_only_fb); + GPU_framebuffer_bind(framebuffer); manager.submit(grid_ps_, view); } diff --git a/source/blender/draw/engines/overlay/overlay_next_instance.cc b/source/blender/draw/engines/overlay/overlay_next_instance.cc index cd4323cc9a6..b065c2638e9 100644 --- a/source/blender/draw/engines/overlay/overlay_next_instance.cc +++ b/source/blender/draw/engines/overlay/overlay_next_instance.cc @@ -260,21 +260,23 @@ void Instance::draw(Manager &manager) const DRWView *view_legacy = DRW_view_default_get(); View view("OverlayView", view_legacy); - if (state.xray_enabled) { - /* For X-ray we render the scene to a separate depth buffer. */ - resources.xray_depth_tx.acquire(render_size, GPU_DEPTH24_STENCIL8); - resources.depth_target_tx.wrap(resources.xray_depth_tx); - } - else { - resources.depth_target_tx.wrap(resources.depth_tx); - } - /* TODO(fclem): Remove mandatory allocation. */ if (!resources.depth_in_front_tx.is_valid()) { resources.depth_in_front_alloc_tx.acquire(render_size, GPU_DEPTH24_STENCIL8); resources.depth_in_front_tx.wrap(resources.depth_in_front_alloc_tx); } + if (state.xray_enabled) { + /* For X-ray we render the scene to a separate depth buffer. */ + resources.xray_depth_tx.acquire(render_size, GPU_DEPTH24_STENCIL8); + resources.depth_target_tx.wrap(resources.xray_depth_tx); + resources.depth_target_in_front_tx.wrap(resources.xray_depth_tx); + } + else { + resources.depth_target_tx.wrap(resources.depth_tx); + resources.depth_target_in_front_tx.wrap(resources.depth_in_front_tx); + } + /* TODO: Better semantics using a switch? */ if (!resources.color_overlay_tx.is_valid()) { /* Likely to be the selection case. Allocate dummy texture and bind only depth buffer. */ @@ -303,11 +305,13 @@ void Instance::draw(Manager &manager) resources.overlay_line_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_target_tx), GPU_ATTACHMENT_TEXTURE(resources.overlay_tx), GPU_ATTACHMENT_TEXTURE(resources.line_tx)); - resources.overlay_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx), - GPU_ATTACHMENT_TEXTURE(resources.overlay_tx)); - resources.overlay_line_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx), - GPU_ATTACHMENT_TEXTURE(resources.overlay_tx), - GPU_ATTACHMENT_TEXTURE(resources.line_tx)); + resources.overlay_in_front_fb.ensure( + GPU_ATTACHMENT_TEXTURE(resources.depth_target_in_front_tx), + GPU_ATTACHMENT_TEXTURE(resources.overlay_tx)); + resources.overlay_line_in_front_fb.ensure( + GPU_ATTACHMENT_TEXTURE(resources.depth_target_in_front_tx), + GPU_ATTACHMENT_TEXTURE(resources.overlay_tx), + GPU_ATTACHMENT_TEXTURE(resources.line_tx)); } resources.overlay_line_only_fb.ensure(GPU_ATTACHMENT_NONE, @@ -346,8 +350,6 @@ void Instance::draw(Manager &manager) layer.facing.draw(framebuffer, manager, view); }; - overlay_fb_draw(regular, resources.overlay_fb); - auto draw_layer = [&](OverlayLayer &layer, Framebuffer &framebuffer) { layer.bounds.draw(framebuffer, manager, view); layer.wireframe.draw(framebuffer, manager, view); @@ -365,29 +367,30 @@ void Instance::draw(Manager &manager) layer.meshes.draw(framebuffer, manager, view); }; - draw_layer(regular, resources.overlay_line_fb); - - xray_fade.draw(manager); - auto draw_layer_color_only = [&](OverlayLayer &layer, Framebuffer &framebuffer) { layer.light_probes.draw_color_only(framebuffer, manager, view); layer.meshes.draw_color_only(framebuffer, manager, view); layer.curves.draw_color_only(framebuffer, manager, view); }; + overlay_fb_draw(regular, resources.overlay_fb); + draw_layer(regular, resources.overlay_line_fb); + + overlay_fb_draw(infront, resources.overlay_in_front_fb); + draw_layer(infront, resources.overlay_line_in_front_fb); + + xray_fade.draw(resources.overlay_color_only_fb, manager, view); + grid.draw(resources.overlay_color_only_fb, manager, view); + draw_layer_color_only(regular, resources.overlay_color_only_fb); + draw_layer_color_only(infront, resources.overlay_color_only_fb); - grid.draw(resources, manager, view); + infront.empties.draw_in_front_images(resources.overlay_color_only_fb, manager, view); + regular.cameras.draw_in_front(resources.overlay_color_only_fb, manager, view); + infront.cameras.draw_in_front(resources.overlay_color_only_fb, manager, view); - /* TODO(: Breaks selection on M1 Max. */ - // infront.lattices.draw(resources.overlay_line_in_front_fb, manager, view); - // infront.empties.draw_in_front_images(resources.overlay_in_front_fb, manager, view); - // regular.cameras.draw_in_front(resources.overlay_in_front_fb, manager, view); - // infront.cameras.draw_in_front(resources.overlay_in_front_fb, manager, view); - - /* Drawn onto the output framebuffer. */ - background.draw(manager); - anti_aliasing.draw(manager); + background.draw(resources.overlay_output_fb, manager, view); + anti_aliasing.draw(resources.overlay_output_fb, manager, view); resources.line_tx.release(); resources.overlay_tx.release(); diff --git a/source/blender/draw/engines/overlay/overlay_next_private.hh b/source/blender/draw/engines/overlay/overlay_next_private.hh index e13ff991a1f..c8714051d53 100644 --- a/source/blender/draw/engines/overlay/overlay_next_private.hh +++ b/source/blender/draw/engines/overlay/overlay_next_private.hh @@ -198,7 +198,7 @@ class ShaderModule { ShaderPtr outline_prepass_pointcloud; ShaderPtr outline_prepass_gpencil; ShaderPtr outline_detect = shader("overlay_outline_detect"); - ShaderPtr xray_fade = shader("overlay_xray_fade"); + ShaderPtr xray_fade; /** Selectable Shaders */ ShaderPtr armature_sphere_outline; @@ -303,6 +303,7 @@ struct Resources : public select::SelectMap { * or `xray_depth_tx` if X-ray is enabled. */ TextureRef depth_target_tx; + TextureRef depth_target_in_front_tx; Vector bg_movie_clips; diff --git a/source/blender/draw/engines/overlay/overlay_next_shader.cc b/source/blender/draw/engines/overlay/overlay_next_shader.cc index 179eee63849..7ce23f2cda1 100644 --- a/source/blender/draw/engines/overlay/overlay_next_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_next_shader.cc @@ -219,6 +219,10 @@ ShaderModule::ShaderModule(const SelectionType selection_type, const bool clippi info.additional_info("draw_gpencil_new", "draw_object_infos_new"); }); + xray_fade = shader("overlay_xray_fade", [](gpu::shader::ShaderCreateInfo &info) { + info.sampler(2, ImageType::DEPTH_2D, "xrayDepthTexInfront"); + }); + /** Selectable Shaders */ armature_sphere_outline = selectable_shader( diff --git a/source/blender/draw/engines/overlay/overlay_next_xray_fade.hh b/source/blender/draw/engines/overlay/overlay_next_xray_fade.hh index 35f373522fa..d2d0fa503bb 100644 --- a/source/blender/draw/engines/overlay/overlay_next_xray_fade.hh +++ b/source/blender/draw/engines/overlay/overlay_next_xray_fade.hh @@ -44,17 +44,19 @@ class XrayFade { * and overlay next. To be renamed after shaders are not shared anymore. */ pass.bind_texture("depthTex", &res.xray_depth_tx); pass.bind_texture("xrayDepthTex", &res.depth_tx); + pass.bind_texture("xrayDepthTexInfront", &res.depth_in_front_tx); pass.push_constant("opacity", 1.0f - state.xray_opacity); pass.draw_procedural(GPU_PRIM_TRIS, 1, 3); } } - void draw(Manager &manager) + void draw(Framebuffer &framebuffer, Manager &manager, View & /*view*/) { if (!enabled_) { return; } + GPU_framebuffer_bind(framebuffer); manager.submit(xray_fade_ps_); } }; diff --git a/source/blender/draw/engines/overlay/shaders/overlay_xray_fade_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_xray_fade_frag.glsl index 990afe0d533..2dbc269edfd 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_xray_fade_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_xray_fade_frag.glsl @@ -6,5 +6,16 @@ void main() { float depth = texture(depthTex, uvcoordsvar.xy).r; float depth_xray = texture(xrayDepthTex, uvcoordsvar.xy).r; +#ifdef OVERLAY_NEXT + float depth_xray_infront = texture(xrayDepthTexInfront, uvcoordsvar.xy).r; + if (((depth_xray_infront == 1.0) && (depth > depth_xray)) || (depth > depth_xray_infront)) { + fragColor = vec4(opacity); + } + else { + discard; + return; + } +#else fragColor = vec4((depth < 1.0 && depth > depth_xray) ? opacity : 1.0); +#endif }