Skip to content

Commit bae9369

Browse files
committed
Improved render sorting for forward renders
1 parent 34f005d commit bae9369

19 files changed

+136
-37
lines changed

doc/classes/RenderingServer.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,6 +1985,7 @@
19851985
<param index="0" name="instance" type="RID" />
19861986
<param index="1" name="sorting_offset" type="float" />
19871987
<param index="2" name="use_aabb_center" type="bool" />
1988+
<param index="3" name="stacked_sorting_offset" type="int" default="0" />
19881989
<description>
19891990
Sets the sorting offset and switches between using the bounding box or instance origin for depth sorting.
19901991
</description>

doc/classes/VisualInstance3D.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,8 @@
7070
If [code]true[/code], the object is sorted based on the [AABB] center. The object will be sorted based on the global position otherwise.
7171
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].
7272
</member>
73+
<member name="sorting_stacked_offset" type="int" setter="set_stacked_sorting_offset" getter="get_stacked_sorting_offset" default="0">
74+
How this [VisualInstance3D] will be adjusted when sorting depth is the same as the other [VisualInstance3D]. Adjusting it to a higher value will make the [VisualInstance3D] reliably draw on top of other [VisualInstance3D]s that are otherwise positioned at exact the same spot.
75+
</member>
7376
</members>
7477
</class>

drivers/gles3/rasterizer_scene_gles3.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,7 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
12711271
}
12721272
inst->depth = p_render_data->cam_transform.origin.distance_to(center) - inst->sorting_offset;
12731273
}
1274+
12741275
uint32_t depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
12751276

12761277
uint32_t flags = inst->base_flags; //fill flags if appropriate

scene/3d/decal.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ void Decal::_validate_property(PropertyInfo &p_property) const {
171171
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
172172
}
173173

174-
if (p_property.name == "sorting_offset") {
174+
if (p_property.name == "sorting_offset" || p_property.name == "stacked_sorting_offset") {
175175
p_property.usage = PROPERTY_USAGE_DEFAULT;
176176
}
177177
}

scene/3d/visual_instance_3d.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,24 +149,33 @@ bool VisualInstance3D::get_layer_mask_value(int p_layer_number) const {
149149

150150
void VisualInstance3D::set_sorting_offset(float p_offset) {
151151
sorting_offset = p_offset;
152-
RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center);
152+
RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center, stacked_sorting_offset);
153153
}
154154

155155
float VisualInstance3D::get_sorting_offset() const {
156156
return sorting_offset;
157157
}
158158

159+
void VisualInstance3D::set_stacked_sorting_offset(float p_offset) {
160+
stacked_sorting_offset = p_offset;
161+
RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center, stacked_sorting_offset);
162+
}
163+
164+
float VisualInstance3D::get_stacked_sorting_offset() const {
165+
return stacked_sorting_offset;
166+
}
167+
159168
void VisualInstance3D::set_sorting_use_aabb_center(bool p_enabled) {
160169
sorting_use_aabb_center = p_enabled;
161-
RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center);
170+
RenderingServer::get_singleton()->instance_set_pivot_data(instance, sorting_offset, sorting_use_aabb_center, stacked_sorting_offset);
162171
}
163172

164173
bool VisualInstance3D::is_sorting_use_aabb_center() const {
165174
return sorting_use_aabb_center;
166175
}
167176

168177
void VisualInstance3D::_validate_property(PropertyInfo &p_property) const {
169-
if (p_property.name == "sorting_offset" || p_property.name == "sorting_use_aabb_center") {
178+
if (p_property.name == "sorting_offset" || p_property.name == "sorting_use_aabb_center" || p_property.name == "stacked_sorting_offset") {
170179
p_property.usage = PROPERTY_USAGE_NONE;
171180
}
172181
}
@@ -181,6 +190,8 @@ void VisualInstance3D::_bind_methods() {
181190
ClassDB::bind_method(D_METHOD("get_layer_mask_value", "layer_number"), &VisualInstance3D::get_layer_mask_value);
182191
ClassDB::bind_method(D_METHOD("set_sorting_offset", "offset"), &VisualInstance3D::set_sorting_offset);
183192
ClassDB::bind_method(D_METHOD("get_sorting_offset"), &VisualInstance3D::get_sorting_offset);
193+
ClassDB::bind_method(D_METHOD("set_stacked_sorting_offset", "offset"), &VisualInstance3D::set_stacked_sorting_offset);
194+
ClassDB::bind_method(D_METHOD("get_stacked_sorting_offset"), &VisualInstance3D::get_stacked_sorting_offset);
184195
ClassDB::bind_method(D_METHOD("set_sorting_use_aabb_center", "enabled"), &VisualInstance3D::set_sorting_use_aabb_center);
185196
ClassDB::bind_method(D_METHOD("is_sorting_use_aabb_center"), &VisualInstance3D::is_sorting_use_aabb_center);
186197

@@ -190,6 +201,7 @@ void VisualInstance3D::_bind_methods() {
190201
ADD_GROUP("Sorting", "sorting_");
191202
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sorting_offset"), "set_sorting_offset", "get_sorting_offset");
192203
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sorting_use_aabb_center"), "set_sorting_use_aabb_center", "is_sorting_use_aabb_center");
204+
ADD_PROPERTY(PropertyInfo(Variant::INT, "sorting_stacked_offset"), "set_stacked_sorting_offset", "get_stacked_sorting_offset");
193205
}
194206

195207
void VisualInstance3D::set_base(const RID &p_base) {
@@ -537,7 +549,7 @@ PackedStringArray GeometryInstance3D::get_configuration_warnings() const {
537549
}
538550

539551
void GeometryInstance3D::_validate_property(PropertyInfo &p_property) const {
540-
if (p_property.name == "sorting_offset" || p_property.name == "sorting_use_aabb_center") {
552+
if (p_property.name == "sorting_offset" || p_property.name == "sorting_use_aabb_center" || p_property.name == "stacked_sorting_offset") {
541553
p_property.usage = PROPERTY_USAGE_DEFAULT;
542554
}
543555
}

scene/3d/visual_instance_3d.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class VisualInstance3D : public Node3D {
4040
uint32_t layers = 1;
4141
float sorting_offset = 0.0;
4242
bool sorting_use_aabb_center = true;
43+
int32_t stacked_sorting_offset = 0;
4344

4445
protected:
4546
void _update_visibility();
@@ -75,6 +76,9 @@ class VisualInstance3D : public Node3D {
7576
void set_sorting_offset(float p_offset);
7677
float get_sorting_offset() const;
7778

79+
void set_stacked_sorting_offset(float p_stacked_sorting_offset);
80+
float get_stacked_sorting_offset() const;
81+
7882
void set_sorting_use_aabb_center(bool p_enabled);
7983
bool is_sorting_use_aabb_center() const;
8084

servers/rendering/dummy/rasterizer_scene_dummy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class RasterizerSceneDummy : public RendererSceneRender {
5050
virtual void set_mesh_instance(RID p_mesh_instance) override {}
5151
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override {}
5252
virtual void reset_motion_vectors() override {}
53-
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) override {}
53+
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center, int32_t p_stacked_sorting_offset = 0) override {}
5454
virtual void set_lod_bias(float p_lod_bias) override {}
5555
virtual void set_layer_mask(uint32_t p_layer_mask) override {}
5656
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 {}

servers/rendering/renderer_geometry_instance.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,10 @@ void RenderGeometryInstanceBase::set_transform(const Transform3D &p_transform, c
8080
lod_model_scale = max_scale;
8181
}
8282

83-
void RenderGeometryInstanceBase::set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) {
83+
void RenderGeometryInstanceBase::set_pivot_data(float p_sorting_offset, bool p_use_aabb_center, int32_t p_stacked_sorting_offset) {
8484
sorting_offset = p_sorting_offset;
8585
use_aabb_center = p_use_aabb_center;
86+
stacked_sorting_offset = p_stacked_sorting_offset;
8687
}
8788

8889
void RenderGeometryInstanceBase::set_lod_bias(float p_lod_bias) {

servers/rendering/renderer_geometry_instance.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class RenderGeometryInstance {
4848
virtual void set_surface_materials(const Vector<RID> &p_materials) = 0;
4949
virtual void set_mesh_instance(RID p_mesh_instance) = 0;
5050
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) = 0;
51-
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) = 0;
51+
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center, int32_t p_stacked_sorting_offset) = 0;
5252
virtual void set_lod_bias(float p_lod_bias) = 0;
5353
virtual void set_layer_mask(uint32_t p_layer_mask) = 0;
5454
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;
@@ -94,6 +94,8 @@ class RenderGeometryInstanceBase : public RenderGeometryInstance {
9494
float lod_bias = 0.0;
9595
float sorting_offset = 0.0;
9696
bool use_aabb_center = true;
97+
//used for with overlapping depth sort
98+
int32_t stacked_sorting_offset = 0;
9799

98100
uint32_t layer_mask = 1;
99101

@@ -136,7 +138,7 @@ class RenderGeometryInstanceBase : public RenderGeometryInstance {
136138
virtual void set_surface_materials(const Vector<RID> &p_materials) override;
137139
virtual void set_mesh_instance(RID p_mesh_instance) override;
138140
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
139-
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) override;
141+
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center, int32_t p_stacked_sorting_offset = 0) override;
140142
virtual void set_lod_bias(float p_lod_bias) override;
141143
virtual void set_layer_mask(uint32_t p_layer_mask) override;
142144
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;

servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,15 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
18501850
_fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_voxelgi, using_motion_pass);
18511851
render_list[RENDER_LIST_OPAQUE].sort_by_key();
18521852
render_list[RENDER_LIST_MOTION].sort_by_key();
1853-
render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority();
1853+
1854+
// sorts in the order of:
1855+
// 1. material priority
1856+
// 2. object depth
1857+
// 3. stacked sorting offset
1858+
// 4. surface index
1859+
// 5. material depth used for next-pass sorting
1860+
// 6. geometry id used for constant buffer sorting
1861+
render_list[RENDER_LIST_ALPHA].sort_by_standard_scene_sort();
18541862

18551863
int *render_info = p_render_data->render_info ? p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE] : (int *)nullptr;
18561864
_fill_instance_data(RENDER_LIST_OPAQUE, render_info);
@@ -3954,7 +3962,7 @@ void RenderForwardClustered::_update_global_pipeline_data_requirements_from_ligh
39543962
global_pipeline_data_required.use_shadow_dual_paraboloid = light_storage->get_shadow_dual_paraboloid_used();
39553963
}
39563964

3957-
void RenderForwardClustered::_geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) {
3965+
void RenderForwardClustered::_geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_material_depth, uint32_t p_shader_id, RID p_mesh) {
39583966
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
39593967
uint32_t flags = 0;
39603968

@@ -4049,6 +4057,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
40494057

40504058
sdcache->sort.surface_index = p_surface;
40514059
sdcache->sort.material_id = p_material_id;
4060+
sdcache->sort.material_depth = p_material_depth;
40524061
sdcache->sort.shader_id = p_shader_id;
40534062
sdcache->sort.geometry_id = p_mesh.get_local_index(); //only meshes can repeat anyway
40544063
sdcache->sort.uses_forward_gi = ginstance->can_sdfgi;
@@ -4078,9 +4087,11 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material_chain(
40784087
SceneShaderForwardClustered::MaterialData *material = p_material;
40794088
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
40804089

4081-
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, p_mat_src.get_local_index(), material_storage->material_get_shader_id(p_mat_src), p_mesh);
4090+
uint32_t material_depth = 0;
4091+
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, p_mat_src.get_local_index(), material_depth, material_storage->material_get_shader_id(p_mat_src), p_mesh);
40824092

40834093
while (material->next_pass.is_valid()) {
4094+
material_depth++;
40844095
RID next_pass = material->next_pass;
40854096
material = static_cast<SceneShaderForwardClustered::MaterialData *>(material_storage->material_get_data(next_pass, RendererRD::MaterialStorage::SHADER_TYPE_3D));
40864097
if (!material || !material->shader_data->is_valid()) {
@@ -4089,7 +4100,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material_chain(
40894100
if (ginstance->data->dirty_dependencies) {
40904101
material_storage->material_update_dependency(next_pass, &ginstance->data->dependency_tracker);
40914102
}
4092-
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), material_storage->material_get_shader_id(next_pass), p_mesh);
4103+
_geometry_instance_add_surface_with_material(ginstance, p_surface, material, next_pass.get_local_index(), material_depth, material_storage->material_get_shader_id(next_pass), p_mesh);
40934104
}
40944105
}
40954106

0 commit comments

Comments
 (0)