Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] Add options for sorting transparent objects #63040

Merged
merged 1 commit into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/classes/VisualInstance.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
</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>
<constants>
</constants>
Expand Down
28 changes: 28 additions & 0 deletions scene/3d/visual_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,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;
VisualServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center);
}

float VisualInstance::get_sorting_offset() {
YuriSizov marked this conversation as resolved.
Show resolved Hide resolved
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() {
YuriSizov marked this conversation as resolved.
Show resolved Hide resolved
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);
Expand All @@ -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("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) {
Expand All @@ -207,6 +233,8 @@ VisualInstance::VisualInstance() {
instance = RID_PRIME(VisualServer::get_singleton()->instance_create());
VisualServer::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);
}

Expand Down
8 changes: 8 additions & 0 deletions scene/3d/visual_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,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;

Expand Down Expand Up @@ -77,6 +79,12 @@ class VisualInstance : public CullInstance {
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();
};
Expand Down
1 change: 1 addition & 0 deletions servers/visual/visual_server_raster.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ class VisualServerRaster : public VisualServer {
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)
Expand Down
17 changes: 14 additions & 3 deletions servers/visual/visual_server_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,14 @@ void VisualServerScene::instance_set_layer_mask(RID p_instance, uint32_t 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) {
Instance *instance = instance_owner.get(p_instance);
ERR_FAIL_COND(!instance);
Expand Down Expand Up @@ -3267,11 +3275,14 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
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) {
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;
neikeq marked this conversation as resolved.
Show resolved Hide resolved
}
ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15);
}
Expand Down
5 changes: 5 additions & 0 deletions servers/visual/visual_server_scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ class VisualServerScene {
AABB aabb;
AABB transformed_aabb;
AABB *custom_aabb; // <Zylann> would using aabb directly with a bool be better?
float sorting_offset;
bool use_aabb_center;
float extra_margin;
uint32_t object_id;

Expand Down Expand Up @@ -371,6 +373,8 @@ class VisualServerScene {
base_data = nullptr;

custom_aabb = nullptr;
sorting_offset = 0.0f;
use_aabb_center = false;
}

~Instance() {
Expand Down Expand Up @@ -614,6 +618,7 @@ class VisualServerScene {
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);
Expand Down
1 change: 1 addition & 0 deletions servers/visual/visual_server_wrap_mt.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ class VisualServerWrapMT : public VisualServer {
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)
Expand Down
1 change: 1 addition & 0 deletions servers/visual_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,7 @@ class VisualServer : public Object {
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;
Expand Down