From 30724ddecd1ff36e7b368759958640f16d1ce393 Mon Sep 17 00:00:00 2001 From: Laurynas Duburas Date: Wed, 11 Sep 2024 17:29:26 +0200 Subject: [PATCH] Overlay-Next: Fade Overlay-Next version of Fade in Mesh edit mode and Fade geometry in armature pose mode. Rel #102179 Pull Request: https://projects.blender.org/blender/blender/pulls/127247 --- source/blender/draw/CMakeLists.txt | 1 + .../engines/overlay/overlay_next_armature.hh | 2 +- .../engines/overlay/overlay_next_facing.hh | 11 +- .../draw/engines/overlay/overlay_next_fade.hh | 167 ++++++++++++++++++ .../engines/overlay/overlay_next_instance.cc | 4 + .../engines/overlay/overlay_next_instance.hh | 2 + .../engines/overlay/overlay_next_prepass.hh | 9 +- .../engines/overlay/overlay_next_private.hh | 19 +- .../engines/overlay/overlay_next_shader.cc | 6 + source/blender/draw/intern/draw_manager.hh | 13 ++ 10 files changed, 220 insertions(+), 14 deletions(-) create mode 100644 source/blender/draw/engines/overlay/overlay_next_fade.hh diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 9052b468852..c03cddd30e2 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -295,6 +295,7 @@ set(SRC engines/overlay/overlay_next_curve.hh engines/overlay/overlay_next_empty.hh engines/overlay/overlay_next_facing.hh + engines/overlay/overlay_next_fade.hh engines/overlay/overlay_next_fluid.hh engines/overlay/overlay_next_force_field.hh engines/overlay/overlay_next_grease_pencil.hh diff --git a/source/blender/draw/engines/overlay/overlay_next_armature.hh b/source/blender/draw/engines/overlay/overlay_next_armature.hh index baaf3602df2..d047beda98e 100644 --- a/source/blender/draw/engines/overlay/overlay_next_armature.hh +++ b/source/blender/draw/engines/overlay/overlay_next_armature.hh @@ -133,7 +133,7 @@ class Armatures { void begin_sync(Resources &res, const State &state) { - enabled_ = !(state.overlay.flag & V3D_OVERLAY_HIDE_BONES); + enabled_ = state.v3d && !(state.overlay.flag & V3D_OVERLAY_HIDE_BONES); if (!enabled_) { return; diff --git a/source/blender/draw/engines/overlay/overlay_next_facing.hh b/source/blender/draw/engines/overlay/overlay_next_facing.hh index 654b6ed3a98..7de0cb93a71 100644 --- a/source/blender/draw/engines/overlay/overlay_next_facing.hh +++ b/source/blender/draw/engines/overlay/overlay_next_facing.hh @@ -64,14 +64,17 @@ class Facing { !DRW_state_is_image_render(); if (use_sculpt_pbvh) { - /* TODO: Add sculpt mode. */ - // DRW_shgroup_call_sculpt(pd->facing_grp[is_xray], ob, false, false, false, false, false); + ResourceHandle handle = manager.resource_handle_for_sculpt(ob_ref); + + for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, SCULPT_BATCH_DEFAULT)) { + ps_.draw(batch.batch, handle); + } } else { blender::gpu::Batch *geom = DRW_cache_object_surface_get(ob_ref.object); if (geom) { - ResourceHandle res_handle = manager.resource_handle(ob_ref); - ps_.draw(geom, res_handle); + ResourceHandle handle = manager.resource_handle(ob_ref); + ps_.draw(geom, handle); } } } diff --git a/source/blender/draw/engines/overlay/overlay_next_fade.hh b/source/blender/draw/engines/overlay/overlay_next_fade.hh new file mode 100644 index 00000000000..ea502c87893 --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_next_fade.hh @@ -0,0 +1,167 @@ +/* SPDX-FileCopyrightText: 2024 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup overlay + */ + +#pragma once + +#include "BKE_modifier.hh" +#include "BKE_paint.hh" + +#include "overlay_next_armature.hh" +#include "overlay_next_private.hh" + +namespace blender::draw::overlay { +class Fade { + private: + const SelectionType selection_type_; + + PassMain ps_ = {"FadeGeometry"}; + + PassMain::Sub *mesh_fade_geometry_ps_; + /* Passes for Pose Fade Geometry. */ + PassMain::Sub *armature_fade_geometry_active_ps_; + PassMain::Sub *armature_fade_geometry_other_ps_; + + bool enabled_ = false; + + public: + Fade(const SelectionType selection_type_) : selection_type_(selection_type_) {} + + void begin_sync(Resources &res, const State &state) + { + const bool do_edit_mesh_fade_geom = !state.xray_enabled && + (state.overlay.flag & V3D_OVERLAY_FADE_INACTIVE); + enabled_ = state.v3d && (do_edit_mesh_fade_geom || state.do_pose_fade_geom) && + (selection_type_ == SelectionType::DISABLED); + + if (!enabled_) { + /* Not used. But release the data. */ + ps_.init(); + return; + } + + ps_.init(); + ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA, + state.clipping_plane_count); + ps_.shader_set(res.shaders.uniform_color.get()); + { + PassMain::Sub &sub = ps_.sub("edit_mesh.fade"); + float4 color = res.background_color_get(state); + color[3] = state.overlay.fade_alpha; + if (state.v3d->shading.background_type == V3D_SHADING_BACKGROUND_THEME) { + srgb_to_linearrgb_v4(color, color); + } + sub.push_constant("ucolor", color); + mesh_fade_geometry_ps_ = ⊂ + } + + /* Fade Geometry. */ + if (state.do_pose_fade_geom) { + const float alpha = state.overlay.xray_alpha_bone; + float4 color = {0.0f, 0.0f, 0.0f, alpha}; + { + auto &sub = ps_.sub("fade_geometry.active"); + sub.push_constant("ucolor", color); + armature_fade_geometry_active_ps_ = ⊂ + } + { + color[3] = powf(alpha, 4); + auto &sub = ps_.sub("fade_geometry"); + sub.push_constant("ucolor", color); + armature_fade_geometry_other_ps_ = ⊂ + } + } + } + + void object_sync(Manager &manager, const ObjectRef &ob_ref, const State &state) + { + if (!enabled_) { + return; + } + const Object *ob = ob_ref.object; + const bool renderable = DRW_object_is_renderable(ob); + const bool draw_surface = (ob->dt >= OB_WIRE) && (renderable || (ob->dt == OB_WIRE)); + const bool draw_fade = draw_surface && overlay_should_fade_object(ob, state.object_active); + + const bool draw_bone_selection = (ob_ref.object->type == OB_MESH) && state.do_pose_fade_geom; + + auto fade_sync = + [](Manager &manager, const ObjectRef &ob_ref, const State &state, PassMain::Sub &sub) { + const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob_ref.object, + state.rv3d) && + !DRW_state_is_image_render(); + + if (use_sculpt_pbvh) { + ResourceHandle handle = manager.resource_handle_for_sculpt(ob_ref); + + for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, SCULPT_BATCH_DEFAULT)) { + sub.draw(batch.batch, handle); + } + } + else { + blender::gpu::Batch *geom = DRW_cache_object_surface_get((Object *)ob_ref.object); + if (geom) { + ResourceHandle handle = manager.resource_handle(ob_ref); + sub.draw(geom, handle); + } + } + }; + + if (draw_bone_selection) { + fade_sync(manager, + ob_ref, + state, + is_driven_by_active_armature(ob_ref.object, state) ? + *armature_fade_geometry_active_ps_ : + *armature_fade_geometry_other_ps_); + } + else if (draw_fade) { + fade_sync(manager, ob_ref, state, *mesh_fade_geometry_ps_); + } + } + + void draw(Framebuffer &framebuffer, Manager &manager, View &view) + { + GPU_framebuffer_bind(framebuffer); + manager.submit(ps_, view); + } + + private: + static bool overlay_should_fade_object(const Object *ob, const Object *active_object) + { + if (!active_object || !ob) { + return false; + } + + if (ELEM(active_object->mode, OB_MODE_OBJECT, OB_MODE_POSE)) { + return false; + } + + if ((active_object->mode & ob->mode) != 0) { + return false; + } + + return true; + } + + static bool is_driven_by_active_armature(Object *ob, const State &state) + { + Object *ob_arm = BKE_modifiers_is_deformed_by_armature(ob); + if (ob_arm) { + return Armatures::is_pose_mode(ob_arm, state); + } + + Object *ob_mesh_deform = BKE_modifiers_is_deformed_by_meshdeform(ob); + if (ob_mesh_deform) { + /* Recursive. */ + return is_driven_by_active_armature(ob_mesh_deform, state); + } + + return false; + } +}; +} // namespace blender::draw::overlay diff --git a/source/blender/draw/engines/overlay/overlay_next_instance.cc b/source/blender/draw/engines/overlay/overlay_next_instance.cc index bae54fe015b..64cd9842800 100644 --- a/source/blender/draw/engines/overlay/overlay_next_instance.cc +++ b/source/blender/draw/engines/overlay/overlay_next_instance.cc @@ -33,6 +33,7 @@ void Instance::init() state.rv3d = ctx->rv3d; state.active_base = BKE_view_layer_active_base_get(ctx->view_layer); state.object_mode = ctx->object_mode; + state.object_active = ctx->obact; /* Note there might be less than 6 planes, but we always compute the 6 of them for simplicity. */ state.clipping_plane_count = clipping_enabled_ ? 6 : 0; @@ -105,6 +106,7 @@ void Instance::begin_sync() layer.curves.begin_sync(resources, state, view); layer.empties.begin_sync(resources, state, view); layer.facing.begin_sync(resources, state); + layer.fade.begin_sync(resources, state); layer.force_fields.begin_sync(); layer.fluids.begin_sync(resources, state); layer.lattices.begin_sync(resources, state); @@ -215,6 +217,7 @@ void Instance::object_sync(ObjectRef &ob_ref, Manager &manager) } layer.bounds.object_sync(ob_ref, resources, state); layer.facing.object_sync(manager, ob_ref, state); + layer.fade.object_sync(manager, ob_ref, state); layer.force_fields.object_sync(ob_ref, resources, state); layer.fluids.object_sync(manager, ob_ref, resources, state); layer.particles.object_sync(manager, ob_ref, resources, state); @@ -368,6 +371,7 @@ void Instance::draw(Manager &manager) auto overlay_fb_draw = [&](OverlayLayer &layer, Framebuffer &framebuffer) { layer.facing.draw(framebuffer, manager, view); + layer.fade.draw(framebuffer, manager, view); }; auto draw_layer = [&](OverlayLayer &layer, Framebuffer &framebuffer) { diff --git a/source/blender/draw/engines/overlay/overlay_next_instance.hh b/source/blender/draw/engines/overlay/overlay_next_instance.hh index e400fc23307..3599740d2db 100644 --- a/source/blender/draw/engines/overlay/overlay_next_instance.hh +++ b/source/blender/draw/engines/overlay/overlay_next_instance.hh @@ -18,6 +18,7 @@ #include "overlay_next_curve.hh" #include "overlay_next_empty.hh" #include "overlay_next_facing.hh" +#include "overlay_next_fade.hh" #include "overlay_next_fluid.hh" #include "overlay_next_force_field.hh" #include "overlay_next_grease_pencil.hh" @@ -70,6 +71,7 @@ class Instance { Curves curves; Empties empties = {selection_type_}; Facing facing = {selection_type_}; + Fade fade = {selection_type_}; Fluids fluids = {selection_type_}; ForceFields force_fields = {selection_type_}; GreasePencil grease_pencil; diff --git a/source/blender/draw/engines/overlay/overlay_next_prepass.hh b/source/blender/draw/engines/overlay/overlay_next_prepass.hh index c62fdb5c4a3..84292a71cab 100644 --- a/source/blender/draw/engines/overlay/overlay_next_prepass.hh +++ b/source/blender/draw/engines/overlay/overlay_next_prepass.hh @@ -11,8 +11,6 @@ #pragma once -#include "BKE_pbvh_api.hh" - #include "draw_sculpt.hh" #include "overlay_next_grease_pencil.hh" @@ -147,12 +145,7 @@ class Prepass { void sculpt_sync(Manager &manager, const ObjectRef &ob_ref, Resources &res) { - /* TODO(fclem): Deduplicate with other engine. */ - const blender::Bounds bounds = bke::pbvh::bounds_get(*ob_ref.object->sculpt->pbvh); - const float3 center = math::midpoint(bounds.min, bounds.max); - const float3 half_extent = bounds.max - center; - ResourceHandle handle = manager.resource_handle(ob_ref, nullptr, ¢er, &half_extent); - + ResourceHandle handle = manager.resource_handle_for_sculpt(ob_ref); select::ID select_id = res.select_id(ob_ref); for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, SCULPT_BATCH_DEFAULT)) { diff --git a/source/blender/draw/engines/overlay/overlay_next_private.hh b/source/blender/draw/engines/overlay/overlay_next_private.hh index 2f2cab8c6d3..c364b475dec 100644 --- a/source/blender/draw/engines/overlay/overlay_next_private.hh +++ b/source/blender/draw/engines/overlay/overlay_next_private.hh @@ -53,6 +53,7 @@ struct State { enum eSpace_Type space_type; enum eContextObjectMode ctx_mode; enum eObjectMode object_mode; + const Object *object_active; bool clear_in_front; bool use_in_front; bool is_wireframe_mode; @@ -199,6 +200,7 @@ class ShaderModule { ShaderPtr curve_edit_points; ShaderPtr curve_edit_line; ShaderPtr curve_edit_handles; + ShaderPtr facing; ShaderPtr grid = shader("overlay_grid"); ShaderPtr legacy_curve_edit_wires; ShaderPtr legacy_curve_edit_normals = shader("overlay_edit_curve_normals"); @@ -223,6 +225,7 @@ class ShaderModule { ShaderPtr sculpt_mesh; ShaderPtr sculpt_curves; ShaderPtr sculpt_curves_cage; + ShaderPtr uniform_color; ShaderPtr xray_fade; /** Selectable Shaders */ @@ -246,7 +249,6 @@ class ShaderModule { ShaderPtr extra_wire; ShaderPtr extra_loose_points; ShaderPtr extra_ground_line; - ShaderPtr facing; ShaderPtr fluid_grid_lines_flags; ShaderPtr fluid_grid_lines_flat; ShaderPtr fluid_grid_lines_range; @@ -448,6 +450,21 @@ struct Resources : public select::SelectMap { return background_blend_color(theme_id); } + float4 background_color_get(const State &state) + { + if (state.v3d->shading.background_type == V3D_SHADING_BACKGROUND_WORLD) { + if (state.scene->world) { + return float4(float3(&state.scene->world->horr)); + } + } + else if (state.v3d->shading.background_type == V3D_SHADING_BACKGROUND_VIEWPORT) { + return state.v3d->shading.background_color; + } + float4 color; + UI_GetThemeColor3fv(TH_BACK, color); + return color; + } + void free_movieclips_textures() { /* Free Movie clip textures after rendering */ diff --git a/source/blender/draw/engines/overlay/overlay_next_shader.cc b/source/blender/draw/engines/overlay/overlay_next_shader.cc index 5e300a3b021..3682a75e319 100644 --- a/source/blender/draw/engines/overlay/overlay_next_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_next_shader.cc @@ -481,6 +481,12 @@ ShaderModule::ShaderModule(const SelectionType selection_type, const bool clippi particle_hair = selectable_shader("overlay_particle_hair_next", [](gpu::shader::ShaderCreateInfo & /*info*/) {}); + uniform_color = shader("overlay_uniform_color", [](gpu::shader::ShaderCreateInfo &info) { + info.additional_infos_.clear(); + info.additional_info( + "draw_view", "draw_modelmat_new", "draw_resource_handle_new", "draw_globals"); + }); + wireframe_mesh = selectable_shader("overlay_wireframe", [](gpu::shader::ShaderCreateInfo &info) { info.additional_infos_.clear(); info.define("CUSTOM_DEPTH_BIAS_CONST"); diff --git a/source/blender/draw/intern/draw_manager.hh b/source/blender/draw/intern/draw_manager.hh index 218337c61ed..6e4233f0e13 100644 --- a/source/blender/draw/intern/draw_manager.hh +++ b/source/blender/draw/intern/draw_manager.hh @@ -14,12 +14,16 @@ * \note It is currently work in progress and should replace the old global draw manager. */ +#include "BKE_paint.hh" +#include "BKE_pbvh_api.hh" + #include "BLI_map.hh" #include "BLI_sys_types.h" #include "GPU_material.hh" #include "draw_resource.hh" +#include "draw_sculpt.hh" #include "draw_view.hh" #include @@ -148,6 +152,15 @@ class Manager { */ ResourceHandle resource_handle_for_psys(const ObjectRef ref, const float4x4 &model_matrix); + ResourceHandle resource_handle_for_sculpt(const ObjectRef ref) + { + /* TODO(fclem): Deduplicate with other engine. */ + const blender::Bounds bounds = bke::pbvh::bounds_get(*ref.object->sculpt->pbvh); + const float3 center = math::midpoint(bounds.min, bounds.max); + const float3 half_extent = bounds.max - center; + return resource_handle(ref, nullptr, ¢er, &half_extent); + } + /** Update the bounds of an already created handle. */ void update_handle_bounds(ResourceHandle handle, const ObjectRef ref,