Merge pull request #63040 from QbieShay/sorting-pivot
[3.x] added options for sorting transparent objects
This commit is contained in:
commit
373a67b7a0
8 changed files with 65 additions and 3 deletions
|
@ -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>
|
||||||
|
|
|
@ -180,6 +180,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;
|
||||||
|
VisualServer::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;
|
||||||
|
VisualServer::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);
|
||||||
|
@ -190,8 +208,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) {
|
||||||
|
@ -207,6 +233,8 @@ VisualInstance::VisualInstance() {
|
||||||
instance = RID_PRIME(VisualServer::get_singleton()->instance_create());
|
instance = RID_PRIME(VisualServer::get_singleton()->instance_create());
|
||||||
VisualServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id());
|
VisualServer::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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,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;
|
||||||
|
|
||||||
|
@ -77,6 +79,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();
|
||||||
};
|
};
|
||||||
|
|
|
@ -579,6 +579,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)
|
||||||
|
|
|
@ -792,6 +792,14 @@ void VisualServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
|
||||||
instance->layer_mask = p_mask;
|
instance->layer_mask = p_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VisualServerScene::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 VisualServerScene::instance_reset_physics_interpolation(RID p_instance) {
|
void VisualServerScene::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);
|
||||||
|
@ -3267,11 +3275,14 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
|
||||||
Instance *ins = instance_cull_result[i];
|
Instance *ins = instance_cull_result[i];
|
||||||
|
|
||||||
if (((1 << ins->base_type) & VS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != VS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
|
if (((1 << ins->base_type) & VS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != VS::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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,6 +311,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;
|
||||||
|
|
||||||
|
@ -371,6 +373,8 @@ public:
|
||||||
base_data = nullptr;
|
base_data = nullptr;
|
||||||
|
|
||||||
custom_aabb = nullptr;
|
custom_aabb = nullptr;
|
||||||
|
sorting_offset = 0.0f;
|
||||||
|
use_aabb_center = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Instance() {
|
~Instance() {
|
||||||
|
@ -614,6 +618,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);
|
||||||
|
|
|
@ -484,6 +484,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)
|
||||||
|
|
|
@ -866,6 +866,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;
|
||||||
|
|
Loading…
Reference in a new issue