Ported: added options for sorting transparent objects

- QbieShay, akien-mga, clayjohn
acdcbefa4e
This commit is contained in:
Relintai 2022-09-17 10:54:57 +02:00
parent 64f5bd2339
commit 93eb41c69e
8 changed files with 76 additions and 10 deletions

View File

@ -62,6 +62,13 @@
The render layer(s) this [VisualInstance] is drawn on. 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. This object will only be visible for [Camera]s whose cull mask includes the render object this [VisualInstance] is set to.
</member> </member>
<member name="sorting_offset" type="float" setter="set_sorting_offset" getter="get_sorting_offset" default="0.0">
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.
</member>
<member name="sorting_use_aabb_center" type="bool" setter="set_sorting_use_aabb_center" getter="is_sorting_use_aabb_center" default="true">
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].
</member>
</members> </members>
<constants> <constants>
</constants> </constants>

View File

@ -170,6 +170,24 @@ bool VisualInstance::get_layer_mask_bit(int p_layer) const {
return (layers & (1 << p_layer)); 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() { void VisualInstance::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_visual_instance_rid"), &VisualInstance::_get_visual_instance_rid); 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); 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("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_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("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_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) { void VisualInstance::set_base(const RID &p_base) {
@ -197,6 +223,8 @@ VisualInstance::VisualInstance() {
instance = RID_PRIME(RenderingServer::get_singleton()->instance_create()); instance = RID_PRIME(RenderingServer::get_singleton()->instance_create());
RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id()); RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id());
layers = 1; layers = 1;
sorting_offset = 0.0f;
sorting_use_aabb_center = true;
set_notify_transform(true); set_notify_transform(true);
} }

View File

@ -30,9 +30,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/ /*************************************************************************/
#include "core/containers/rid.h"
#include "core/math/face3.h" #include "core/math/face3.h"
#include "core/object/reference.h" #include "core/object/reference.h"
#include "core/containers/rid.h"
#include "scene/3d/cull_instance.h" #include "scene/3d/cull_instance.h"
#include "servers/rendering_server.h" #include "servers/rendering_server.h"
@ -45,6 +45,8 @@ class VisualInstance : public CullInstance {
RID base; RID base;
RID instance; RID instance;
uint32_t layers; uint32_t layers;
float sorting_offset;
bool sorting_use_aabb_center;
RID _get_visual_instance_rid() const; RID _get_visual_instance_rid() const;
@ -79,6 +81,12 @@ public:
void set_layer_mask_bit(int p_layer, bool p_enable); void set_layer_mask_bit(int p_layer, bool p_enable);
bool get_layer_mask_bit(int p_layer) const; 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();
~VisualInstance(); ~VisualInstance();
}; };

View File

@ -474,6 +474,7 @@ public:
BIND2(instance_set_base, RID, RID) BIND2(instance_set_base, RID, RID)
BIND2(instance_set_scenario, RID, RID) BIND2(instance_set_scenario, RID, RID)
BIND2(instance_set_layer_mask, RID, uint32_t) 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_transform, RID, const Transform &)
BIND2(instance_set_interpolated, RID, bool) BIND2(instance_set_interpolated, RID, bool)
BIND1(instance_reset_physics_interpolation, RID) BIND1(instance_reset_physics_interpolation, RID)

View File

@ -30,9 +30,9 @@
#include "rendering_server_scene.h" #include "rendering_server_scene.h"
#include "core/config/project_settings.h"
#include "core/math/transform_interpolator.h" #include "core/math/transform_interpolator.h"
#include "core/os/os.h" #include "core/os/os.h"
#include "core/config/project_settings.h"
#include "rendering_server_globals.h" #include "rendering_server_globals.h"
#include "rendering_server_raster.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; 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) { void RenderingServerScene::instance_reset_physics_interpolation(RID p_instance) {
Instance *instance = instance_owner.get(p_instance); Instance *instance = instance_owner.get(p_instance);
ERR_FAIL_COND(!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]; 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) { 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) { if (p_cam_orthogonal) {
ins->depth = near_plane.distance_to(aabb_center); ins->depth = near_plane.distance_to(center) - ins->sorting_offset;
} else { } 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); ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15);
} }

View File

@ -32,13 +32,13 @@
#include "servers/rendering/rasterizer.h" #include "servers/rendering/rasterizer.h"
#include "core/containers/self_list.h"
#include "core/math/bvh.h" #include "core/math/bvh.h"
#include "core/math/geometry.h" #include "core/math/geometry.h"
#include "core/math/octree.h" #include "core/math/octree.h"
#include "core/os/safe_refcount.h"
#include "core/os/semaphore.h" #include "core/os/semaphore.h"
#include "core/os/thread.h" #include "core/os/thread.h"
#include "core/os/safe_refcount.h"
#include "core/containers/self_list.h"
#include "portals/portal_renderer.h" #include "portals/portal_renderer.h"
class RenderingServerScene { class RenderingServerScene {
@ -334,6 +334,8 @@ public:
AABB aabb; AABB aabb;
AABB transformed_aabb; AABB transformed_aabb;
AABB *custom_aabb; // <Zylann> would using aabb directly with a bool be better? AABB *custom_aabb; // <Zylann> would using aabb directly with a bool be better?
float sorting_offset;
bool use_aabb_center;
float extra_margin; float extra_margin;
uint32_t object_id; uint32_t object_id;
@ -396,6 +398,8 @@ public:
base_data = nullptr; base_data = nullptr;
custom_aabb = nullptr; custom_aabb = nullptr;
sorting_offset = 0.0f;
use_aabb_center = false;
} }
~Instance() { ~Instance() {
@ -496,6 +500,7 @@ public:
virtual void instance_set_base(RID p_instance, RID p_base); 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_scenario(RID p_instance, RID p_scenario);
virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask); 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_transform(RID p_instance, const Transform &p_transform);
virtual void instance_set_interpolated(RID p_instance, bool p_interpolated); virtual void instance_set_interpolated(RID p_instance, bool p_interpolated);
virtual void instance_reset_physics_interpolation(RID p_instance); virtual void instance_reset_physics_interpolation(RID p_instance);

View File

@ -31,8 +31,8 @@
/*************************************************************************/ /*************************************************************************/
#include "core/containers/command_queue_mt.h" #include "core/containers/command_queue_mt.h"
#include "core/os/thread.h"
#include "core/os/safe_refcount.h" #include "core/os/safe_refcount.h"
#include "core/os/thread.h"
#include "servers/rendering_server.h" #include "servers/rendering_server.h"
class RenderingServerWrapMT : public RenderingServer { class RenderingServerWrapMT : public RenderingServer {
@ -391,6 +391,7 @@ public:
FUNC2(instance_set_base, RID, RID) FUNC2(instance_set_base, RID, RID)
FUNC2(instance_set_scenario, RID, RID) FUNC2(instance_set_scenario, RID, RID)
FUNC2(instance_set_layer_mask, RID, uint32_t) 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_transform, RID, const Transform &)
FUNC2(instance_set_interpolated, RID, bool) FUNC2(instance_set_interpolated, RID, bool)
FUNC1(instance_reset_physics_interpolation, RID) FUNC1(instance_reset_physics_interpolation, RID)
@ -608,8 +609,12 @@ public:
FUNC1(set_debug_generate_wireframes, bool) FUNC1(set_debug_generate_wireframes, bool)
virtual bool has_feature(Features p_feature) const { return rendering_server->has_feature(p_feature); } virtual bool has_feature(Features p_feature) const {
virtual bool has_os_feature(const String &p_feature) const { return rendering_server->has_os_feature(p_feature); } 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) FUNC1(call_set_use_vsync, bool)

View File

@ -763,6 +763,7 @@ public:
virtual void instance_set_base(RID p_instance, RID p_base) = 0; 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_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_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_transform(RID p_instance, const Transform &p_transform) = 0;
virtual void instance_set_interpolated(RID p_instance, bool p_interpolated) = 0; virtual void instance_set_interpolated(RID p_instance, bool p_interpolated) = 0;
virtual void instance_reset_physics_interpolation(RID p_instance) = 0; virtual void instance_reset_physics_interpolation(RID p_instance) = 0;