Merge pull request #69998 from BastiaanOlij/sorting-pivot-4
Added options for sorting transparent objects (port of PR #63040)
This commit is contained in:
commit
1cab6c91e9
|
@ -1586,6 +1586,15 @@
|
|||
Sets the render layers that this instance will be drawn to. Equivalent to [member VisualInstance3D.layers].
|
||||
</description>
|
||||
</method>
|
||||
<method name="instance_set_pivot_data">
|
||||
<return type="void" />
|
||||
<param index="0" name="instance" type="RID" />
|
||||
<param index="1" name="sorting_offset" type="float" />
|
||||
<param index="2" name="use_aabb_center" type="bool" />
|
||||
<description>
|
||||
Sets the sorting offset and switches between using the bounding box or instance origin for depth sorting.
|
||||
</description>
|
||||
</method>
|
||||
<method name="instance_set_scenario">
|
||||
<return type="void" />
|
||||
<param index="0" name="instance" type="RID" />
|
||||
|
|
|
@ -61,5 +61,12 @@
|
|||
This object will only be visible for [Camera3D]s whose cull mask includes the render object this [VisualInstance3D] is set to.
|
||||
For [Light3D]s, this can be used to control which [VisualInstance3D]s are affected by a specific light. For [GPUParticles3D], this can be used to control which particles are effected by a specific attractor. For [Decal]s, this can be used to control which [VisualInstance3D]s are affected by a specific decal.
|
||||
</member>
|
||||
<member name="sorting_offset" type="float" setter="set_sorting_offset" getter="get_sorting_offset" default="0.0">
|
||||
The sorting offset used by this [VisualInstance3D]. Adjusting it to a higher value will make the [VisualInstance3D] reliably draw on top of other [VisualInstance3D]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. The object will be 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 [GPUParticles3D] and [CPUParticles3D].
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
|
|
@ -1170,12 +1170,17 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
|
|||
for (int i = 0; i < (int)p_render_data->instances->size(); i++) {
|
||||
GeometryInstanceGLES3 *inst = static_cast<GeometryInstanceGLES3 *>((*p_render_data->instances)[i]);
|
||||
|
||||
Vector3 center = inst->transform.origin;
|
||||
if (p_render_data->cam_orthogonal) {
|
||||
Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
|
||||
inst->depth = near_plane.distance_to(support_min);
|
||||
if (inst->use_aabb_center) {
|
||||
center = inst->transformed_aabb.get_support(-near_plane.normal);
|
||||
}
|
||||
inst->depth = near_plane.distance_to(center) - inst->sorting_offset;
|
||||
} else {
|
||||
Vector3 aabb_center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);
|
||||
inst->depth = p_render_data->cam_transform.origin.distance_to(aabb_center);
|
||||
if (inst->use_aabb_center) {
|
||||
center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);
|
||||
}
|
||||
inst->depth = p_render_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;
|
||||
}
|
||||
uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
|
||||
|
||||
|
|
|
@ -102,6 +102,24 @@ bool VisualInstance3D::get_layer_mask_value(int p_layer_number) const {
|
|||
return layers & (1 << (p_layer_number - 1));
|
||||
}
|
||||
|
||||
void VisualInstance3D::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 VisualInstance3D::get_sorting_offset() const {
|
||||
return sorting_offset;
|
||||
}
|
||||
|
||||
void VisualInstance3D::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 VisualInstance3D::is_sorting_use_aabb_center() const {
|
||||
return sorting_use_aabb_center;
|
||||
}
|
||||
|
||||
void VisualInstance3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_base", "base"), &VisualInstance3D::set_base);
|
||||
ClassDB::bind_method(D_METHOD("get_base"), &VisualInstance3D::get_base);
|
||||
|
@ -110,9 +128,17 @@ void VisualInstance3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_layer_mask"), &VisualInstance3D::get_layer_mask);
|
||||
ClassDB::bind_method(D_METHOD("set_layer_mask_value", "layer_number", "value"), &VisualInstance3D::set_layer_mask_value);
|
||||
ClassDB::bind_method(D_METHOD("get_layer_mask_value", "layer_number"), &VisualInstance3D::get_layer_mask_value);
|
||||
ClassDB::bind_method(D_METHOD("set_sorting_offset", "offset"), &VisualInstance3D::set_sorting_offset);
|
||||
ClassDB::bind_method(D_METHOD("get_sorting_offset"), &VisualInstance3D::get_sorting_offset);
|
||||
ClassDB::bind_method(D_METHOD("set_sorting_use_aabb_center", "enabled"), &VisualInstance3D::set_sorting_use_aabb_center);
|
||||
ClassDB::bind_method(D_METHOD("is_sorting_use_aabb_center"), &VisualInstance3D::is_sorting_use_aabb_center);
|
||||
|
||||
GDVIRTUAL_BIND(_get_aabb);
|
||||
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::FLOAT, "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 VisualInstance3D::set_base(const RID &p_base) {
|
||||
|
|
|
@ -39,6 +39,8 @@ class VisualInstance3D : public Node3D {
|
|||
RID base;
|
||||
RID instance;
|
||||
uint32_t layers = 1;
|
||||
float sorting_offset = 0.0;
|
||||
bool sorting_use_aabb_center = true;
|
||||
|
||||
protected:
|
||||
void _update_visibility();
|
||||
|
@ -67,6 +69,12 @@ public:
|
|||
void set_layer_mask_value(int p_layer_number, bool p_enable);
|
||||
bool get_layer_mask_value(int p_layer_number) const;
|
||||
|
||||
void set_sorting_offset(float p_offset);
|
||||
float get_sorting_offset() const;
|
||||
|
||||
void set_sorting_use_aabb_center(bool p_enabled);
|
||||
bool is_sorting_use_aabb_center() const;
|
||||
|
||||
VisualInstance3D();
|
||||
~VisualInstance3D();
|
||||
};
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
virtual void set_surface_materials(const Vector<RID> &p_materials) override {}
|
||||
virtual void set_mesh_instance(RID p_mesh_instance) override {}
|
||||
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override {}
|
||||
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) override {}
|
||||
virtual void set_lod_bias(float p_lod_bias) override {}
|
||||
virtual void set_layer_mask(uint32_t p_layer_mask) override {}
|
||||
virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override {}
|
||||
|
|
|
@ -80,6 +80,11 @@ void RenderGeometryInstanceBase::set_transform(const Transform3D &p_transform, c
|
|||
lod_model_scale = max_scale;
|
||||
}
|
||||
|
||||
void RenderGeometryInstanceBase::set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) {
|
||||
sorting_offset = p_sorting_offset;
|
||||
use_aabb_center = p_use_aabb_center;
|
||||
}
|
||||
|
||||
void RenderGeometryInstanceBase::set_lod_bias(float p_lod_bias) {
|
||||
lod_bias = p_lod_bias;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
virtual void set_surface_materials(const Vector<RID> &p_materials) = 0;
|
||||
virtual void set_mesh_instance(RID p_mesh_instance) = 0;
|
||||
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) = 0;
|
||||
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) = 0;
|
||||
virtual void set_lod_bias(float p_lod_bias) = 0;
|
||||
virtual void set_layer_mask(uint32_t p_layer_mask) = 0;
|
||||
virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) = 0;
|
||||
|
@ -86,11 +87,13 @@ public:
|
|||
RID mesh_instance;
|
||||
|
||||
Transform3D transform;
|
||||
bool mirror = false; // move into data?
|
||||
AABB transformed_aabb; //needed for LOD
|
||||
bool mirror = false;
|
||||
AABB transformed_aabb;
|
||||
bool non_uniform_scale = false;
|
||||
float lod_model_scale = 1.0;
|
||||
float lod_bias = 0.0;
|
||||
float sorting_offset = 0.0;
|
||||
bool use_aabb_center = true;
|
||||
|
||||
uint32_t layer_mask = 1;
|
||||
|
||||
|
@ -133,6 +136,7 @@ public:
|
|||
virtual void set_surface_materials(const Vector<RID> &p_materials) override;
|
||||
virtual void set_mesh_instance(RID p_mesh_instance) override;
|
||||
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
|
||||
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) override;
|
||||
virtual void set_lod_bias(float p_lod_bias) override;
|
||||
virtual void set_layer_mask(uint32_t p_layer_mask) override;
|
||||
virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override;
|
||||
|
|
|
@ -831,8 +831,18 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
|
|||
for (int i = 0; i < (int)p_render_data->instances->size(); i++) {
|
||||
GeometryInstanceForwardClustered *inst = static_cast<GeometryInstanceForwardClustered *>((*p_render_data->instances)[i]);
|
||||
|
||||
Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
|
||||
inst->depth = near_plane.distance_to(support_min);
|
||||
Vector3 center = inst->transform.origin;
|
||||
if (p_render_data->scene_data->cam_orthogonal) {
|
||||
if (inst->use_aabb_center) {
|
||||
center = inst->transformed_aabb.get_support(-near_plane.normal);
|
||||
}
|
||||
inst->depth = near_plane.distance_to(center) - inst->sorting_offset;
|
||||
} else {
|
||||
if (inst->use_aabb_center) {
|
||||
center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);
|
||||
}
|
||||
inst->depth = p_render_data->scene_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;
|
||||
}
|
||||
uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
|
||||
|
||||
uint32_t flags = inst->base_flags; //fill flags if appropriate
|
||||
|
|
|
@ -1757,8 +1757,18 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
|
|||
for (int i = 0; i < (int)p_render_data->instances->size(); i++) {
|
||||
GeometryInstanceForwardMobile *inst = static_cast<GeometryInstanceForwardMobile *>((*p_render_data->instances)[i]);
|
||||
|
||||
Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
|
||||
inst->depth = near_plane.distance_to(support_min);
|
||||
Vector3 center = inst->transform.origin;
|
||||
if (p_render_data->scene_data->cam_orthogonal) {
|
||||
if (inst->use_aabb_center) {
|
||||
center = inst->transformed_aabb.get_support(-near_plane.normal);
|
||||
}
|
||||
inst->depth = near_plane.distance_to(center) - inst->sorting_offset;
|
||||
} else {
|
||||
if (inst->use_aabb_center) {
|
||||
center = inst->transformed_aabb.position + (inst->transformed_aabb.size * 0.5);
|
||||
}
|
||||
inst->depth = p_render_data->scene_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;
|
||||
}
|
||||
uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
|
||||
|
||||
uint32_t flags = inst->base_flags; //fill flags if appropriate
|
||||
|
|
|
@ -646,6 +646,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
|||
geom->geometry_instance->set_surface_materials(instance->materials);
|
||||
geom->geometry_instance->set_transform(instance->transform, instance->aabb, instance->transformed_aabb);
|
||||
geom->geometry_instance->set_layer_mask(instance->layer_mask);
|
||||
geom->geometry_instance->set_pivot_data(instance->sorting_offset, instance->use_aabb_center);
|
||||
geom->geometry_instance->set_lod_bias(instance->lod_bias);
|
||||
geom->geometry_instance->set_transparency(instance->transparency);
|
||||
geom->geometry_instance->set_use_baked_light(instance->baked_light);
|
||||
|
@ -844,6 +845,20 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
|
|||
}
|
||||
}
|
||||
|
||||
void RendererSceneCull::instance_set_pivot_data(RID p_instance, float p_sorting_offset, bool p_use_aabb_center) {
|
||||
Instance *instance = instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND(!instance);
|
||||
|
||||
instance->sorting_offset = p_sorting_offset;
|
||||
instance->use_aabb_center = p_use_aabb_center;
|
||||
|
||||
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
|
||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
|
||||
ERR_FAIL_NULL(geom->geometry_instance);
|
||||
geom->geometry_instance->set_pivot_data(p_sorting_offset, p_use_aabb_center);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSceneCull::instance_geometry_set_transparency(RID p_instance, float p_transparency) {
|
||||
Instance *instance = instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND(!instance);
|
||||
|
|
|
@ -459,6 +459,10 @@ public:
|
|||
float extra_margin;
|
||||
ObjectID object_id;
|
||||
|
||||
// sorting
|
||||
float sorting_offset = 0.0;
|
||||
bool use_aabb_center = true;
|
||||
|
||||
Vector<Color> lightmap_target_sh; //target is used for incrementally changing the SH over time, this avoids pops in some corner cases and when going interior <-> exterior
|
||||
|
||||
uint64_t last_frame_pass;
|
||||
|
@ -933,6 +937,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 Transform3D &p_transform);
|
||||
virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id);
|
||||
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight);
|
||||
|
|
|
@ -72,6 +72,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 Transform3D &p_transform) = 0;
|
||||
virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id) = 0;
|
||||
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) = 0;
|
||||
|
|
|
@ -762,6 +762,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 Transform3D &)
|
||||
FUNC2(instance_attach_object_instance_id, RID, ObjectID)
|
||||
FUNC3(instance_set_blend_shape_weight, RID, int, float)
|
||||
|
|
|
@ -2480,6 +2480,7 @@ void RenderingServer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("instance_set_base", "instance", "base"), &RenderingServer::instance_set_base);
|
||||
ClassDB::bind_method(D_METHOD("instance_set_scenario", "instance", "scenario"), &RenderingServer::instance_set_scenario);
|
||||
ClassDB::bind_method(D_METHOD("instance_set_layer_mask", "instance", "mask"), &RenderingServer::instance_set_layer_mask);
|
||||
ClassDB::bind_method(D_METHOD("instance_set_pivot_data", "instance", "sorting_offset", "use_aabb_center"), &RenderingServer::instance_set_pivot_data);
|
||||
ClassDB::bind_method(D_METHOD("instance_set_transform", "instance", "transform"), &RenderingServer::instance_set_transform);
|
||||
ClassDB::bind_method(D_METHOD("instance_attach_object_instance_id", "instance", "id"), &RenderingServer::instance_attach_object_instance_id);
|
||||
ClassDB::bind_method(D_METHOD("instance_set_blend_shape_weight", "instance", "shape", "weight"), &RenderingServer::instance_set_blend_shape_weight);
|
||||
|
|
|
@ -1209,6 +1209,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 Transform3D &p_transform) = 0;
|
||||
virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_id) = 0;
|
||||
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) = 0;
|
||||
|
|
Loading…
Reference in New Issue