From 93eb41c69ee620225608a17f6f6cb4fc3ea06ea0 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 17 Sep 2022 10:54:57 +0200 Subject: [PATCH] Ported: added options for sorting transparent objects - QbieShay, akien-mga, clayjohn https://github.com/godotengine/godot/commit/acdcbefa4eeacc1cb1717f9a2af8f4d02d73d1d3 --- doc/classes/VisualInstance.xml | 7 +++++ scene/3d/visual_instance.cpp | 28 ++++++++++++++++++++ scene/3d/visual_instance.h | 10 ++++++- servers/rendering/rendering_server_raster.h | 1 + servers/rendering/rendering_server_scene.cpp | 19 ++++++++++--- servers/rendering/rendering_server_scene.h | 9 +++++-- servers/rendering/rendering_server_wrap_mt.h | 11 +++++--- servers/rendering_server.h | 1 + 8 files changed, 76 insertions(+), 10 deletions(-) diff --git a/doc/classes/VisualInstance.xml b/doc/classes/VisualInstance.xml index 1bb2c78f9..eebdb1b67 100644 --- a/doc/classes/VisualInstance.xml +++ b/doc/classes/VisualInstance.xml @@ -62,6 +62,13 @@ The render layer(s) this [VisualInstance] is drawn on. This object will only be visible for [Camera]s whose cull mask includes the render object this [VisualInstance] is set to. + + The sorting offset used by this [VisualInstance]. Adjusting it to a higher value will make the [VisualInstance] reliably draw on top of other [VisualInstance]s that are otherwise positioned at the same spot. + + + If [code]true[/code], the object is sorted based on the [AABB] center. Sorted based on the global position otherwise. + The [AABB] center based sorting is generally more accurate for 3D models. The position based sorting instead allows to better control the drawing order when working with [Particles] and [CPUParticles]. + diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index 8099f7421..17f7a32ba 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -170,6 +170,24 @@ bool VisualInstance::get_layer_mask_bit(int p_layer) const { return (layers & (1 << p_layer)); } +void VisualInstance::set_sorting_offset(float p_offset) { + sorting_offset = p_offset; + RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center); +} + +float VisualInstance::get_sorting_offset() { + return sorting_offset; +} + +void VisualInstance::set_sorting_use_aabb_center(bool p_enabled) { + sorting_use_aabb_center = p_enabled; + RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center); +} + +bool VisualInstance::is_sorting_use_aabb_center() { + return sorting_use_aabb_center; +} + void VisualInstance::_bind_methods() { ClassDB::bind_method(D_METHOD("_get_visual_instance_rid"), &VisualInstance::_get_visual_instance_rid); ClassDB::bind_method(D_METHOD("set_base", "base"), &VisualInstance::set_base); @@ -180,8 +198,16 @@ void VisualInstance::_bind_methods() { ClassDB::bind_method(D_METHOD("set_layer_mask_bit", "layer", "enabled"), &VisualInstance::set_layer_mask_bit); ClassDB::bind_method(D_METHOD("get_layer_mask_bit", "layer"), &VisualInstance::get_layer_mask_bit); ClassDB::bind_method(D_METHOD("get_transformed_aabb"), &VisualInstance::get_transformed_aabb); + ClassDB::bind_method(D_METHOD("set_sorting_offset", "offset"), &VisualInstance::set_sorting_offset); + ClassDB::bind_method(D_METHOD("get_sorting_offset"), &VisualInstance::get_sorting_offset); + ClassDB::bind_method(D_METHOD("set_sorting_use_aabb_center", "enabled"), &VisualInstance::set_sorting_use_aabb_center); + ClassDB::bind_method(D_METHOD("is_sorting_use_aabb_center"), &VisualInstance::is_sorting_use_aabb_center); ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_3D_RENDER), "set_layer_mask", "get_layer_mask"); + + ADD_GROUP("Sorting", "sorting_"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "sorting_offset"), "set_sorting_offset", "get_sorting_offset"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sorting_use_aabb_center"), "set_sorting_use_aabb_center", "is_sorting_use_aabb_center"); } void VisualInstance::set_base(const RID &p_base) { @@ -197,6 +223,8 @@ VisualInstance::VisualInstance() { instance = RID_PRIME(RenderingServer::get_singleton()->instance_create()); RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id()); layers = 1; + sorting_offset = 0.0f; + sorting_use_aabb_center = true; set_notify_transform(true); } diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index a321df8d3..079a1f9d1 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -30,9 +30,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#include "core/containers/rid.h" #include "core/math/face3.h" #include "core/object/reference.h" -#include "core/containers/rid.h" #include "scene/3d/cull_instance.h" #include "servers/rendering_server.h" @@ -45,6 +45,8 @@ class VisualInstance : public CullInstance { RID base; RID instance; uint32_t layers; + float sorting_offset; + bool sorting_use_aabb_center; RID _get_visual_instance_rid() const; @@ -79,6 +81,12 @@ public: void set_layer_mask_bit(int p_layer, bool p_enable); bool get_layer_mask_bit(int p_layer) const; + void set_sorting_offset(float p_offset); + float get_sorting_offset(); + + void set_sorting_use_aabb_center(bool p_enabled); + bool is_sorting_use_aabb_center(); + VisualInstance(); ~VisualInstance(); }; diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h index 7b5b7716b..988da81d2 100644 --- a/servers/rendering/rendering_server_raster.h +++ b/servers/rendering/rendering_server_raster.h @@ -474,6 +474,7 @@ public: BIND2(instance_set_base, RID, RID) BIND2(instance_set_scenario, RID, RID) BIND2(instance_set_layer_mask, RID, uint32_t) + BIND3(instance_set_pivot_data, RID, float, bool) BIND2(instance_set_transform, RID, const Transform &) BIND2(instance_set_interpolated, RID, bool) BIND1(instance_reset_physics_interpolation, RID) diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp index cf207979e..259b4dbdb 100644 --- a/servers/rendering/rendering_server_scene.cpp +++ b/servers/rendering/rendering_server_scene.cpp @@ -30,9 +30,9 @@ #include "rendering_server_scene.h" +#include "core/config/project_settings.h" #include "core/math/transform_interpolator.h" #include "core/os/os.h" -#include "core/config/project_settings.h" #include "rendering_server_globals.h" #include "rendering_server_raster.h" @@ -669,6 +669,14 @@ void RenderingServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_ma instance->layer_mask = p_mask; } +void RenderingServerScene::instance_set_pivot_data(RID p_instance, float p_sorting_offset, bool p_use_aabb_center) { + Instance *instance = instance_owner.get(p_instance); + ERR_FAIL_COND(!instance); + + instance->sorting_offset = p_sorting_offset; + instance->use_aabb_center = p_use_aabb_center; +} + void RenderingServerScene::instance_reset_physics_interpolation(RID p_instance) { Instance *instance = instance_owner.get(p_instance); ERR_FAIL_COND(!instance); @@ -2789,11 +2797,14 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const Instance *ins = instance_cull_result[i]; if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) { - Vector3 aabb_center = ins->transformed_aabb.position + (ins->transformed_aabb.size * 0.5); + Vector3 center = ins->transform.origin; + if (ins->use_aabb_center) { + center = ins->transformed_aabb.position + (ins->transformed_aabb.size * 0.5); + } if (p_cam_orthogonal) { - ins->depth = near_plane.distance_to(aabb_center); + ins->depth = near_plane.distance_to(center) - ins->sorting_offset; } else { - ins->depth = p_cam_transform.origin.distance_to(aabb_center); + ins->depth = p_cam_transform.origin.distance_to(center) - ins->sorting_offset; } ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15); } diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h index b86407df4..85cb49f0b 100644 --- a/servers/rendering/rendering_server_scene.h +++ b/servers/rendering/rendering_server_scene.h @@ -32,13 +32,13 @@ #include "servers/rendering/rasterizer.h" +#include "core/containers/self_list.h" #include "core/math/bvh.h" #include "core/math/geometry.h" #include "core/math/octree.h" +#include "core/os/safe_refcount.h" #include "core/os/semaphore.h" #include "core/os/thread.h" -#include "core/os/safe_refcount.h" -#include "core/containers/self_list.h" #include "portals/portal_renderer.h" class RenderingServerScene { @@ -334,6 +334,8 @@ public: AABB aabb; AABB transformed_aabb; AABB *custom_aabb; // would using aabb directly with a bool be better? + float sorting_offset; + bool use_aabb_center; float extra_margin; uint32_t object_id; @@ -396,6 +398,8 @@ public: base_data = nullptr; custom_aabb = nullptr; + sorting_offset = 0.0f; + use_aabb_center = false; } ~Instance() { @@ -496,6 +500,7 @@ public: virtual void instance_set_base(RID p_instance, RID p_base); virtual void instance_set_scenario(RID p_instance, RID p_scenario); virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask); + virtual void instance_set_pivot_data(RID p_instance, float p_sorting_offset, bool p_use_aabb_center); virtual void instance_set_transform(RID p_instance, const Transform &p_transform); virtual void instance_set_interpolated(RID p_instance, bool p_interpolated); virtual void instance_reset_physics_interpolation(RID p_instance); diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index b5e38e4ca..2e4d19791 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -31,8 +31,8 @@ /*************************************************************************/ #include "core/containers/command_queue_mt.h" -#include "core/os/thread.h" #include "core/os/safe_refcount.h" +#include "core/os/thread.h" #include "servers/rendering_server.h" class RenderingServerWrapMT : public RenderingServer { @@ -391,6 +391,7 @@ public: FUNC2(instance_set_base, RID, RID) FUNC2(instance_set_scenario, RID, RID) FUNC2(instance_set_layer_mask, RID, uint32_t) + FUNC3(instance_set_pivot_data, RID, float, bool) FUNC2(instance_set_transform, RID, const Transform &) FUNC2(instance_set_interpolated, RID, bool) FUNC1(instance_reset_physics_interpolation, RID) @@ -608,8 +609,12 @@ public: FUNC1(set_debug_generate_wireframes, bool) - virtual bool has_feature(Features p_feature) const { return rendering_server->has_feature(p_feature); } - virtual bool has_os_feature(const String &p_feature) const { return rendering_server->has_os_feature(p_feature); } + virtual bool has_feature(Features p_feature) const { + return rendering_server->has_feature(p_feature); + } + virtual bool has_os_feature(const String &p_feature) const { + return rendering_server->has_os_feature(p_feature); + } FUNC1(call_set_use_vsync, bool) diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 71b7deac0..1fa899193 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -763,6 +763,7 @@ public: virtual void instance_set_base(RID p_instance, RID p_base) = 0; virtual void instance_set_scenario(RID p_instance, RID p_scenario) = 0; virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask) = 0; + virtual void instance_set_pivot_data(RID p_instance, float p_sorting_offset, bool p_use_aabb_center) = 0; virtual void instance_set_transform(RID p_instance, const Transform &p_transform) = 0; virtual void instance_set_interpolated(RID p_instance, bool p_interpolated) = 0; virtual void instance_reset_physics_interpolation(RID p_instance) = 0;