From 8634a8e2342dff4fba9c12452e947a59f3e0715e Mon Sep 17 00:00:00 2001 From: Mikael Hermansson Date: Fri, 11 Jul 2025 19:41:17 +0200 Subject: [PATCH] Fix performance regression when rendering collision shapes --- modules/gridmap/grid_map.cpp | 10 ++++++- scene/main/scene_tree.cpp | 17 ++++++----- scene/resources/3d/shape_3d.cpp | 52 +++++++++------------------------ scene/resources/3d/shape_3d.h | 3 -- 4 files changed, 31 insertions(+), 51 deletions(-) diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 9329849964f..5e3d1d0889b 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -805,12 +805,20 @@ bool GridMap::_octant_update(const OctantKey &p_key) { #ifndef PHYSICS_3D_DISABLED if (col_debug.size()) { + SceneTree *st = SceneTree::get_singleton(); + + Vector colors; + colors.resize(col_debug.size()); + if (st) { + colors.fill(st->get_debug_collisions_color()); + } + Array arr; arr.resize(RS::ARRAY_MAX); arr[RS::ARRAY_VERTEX] = col_debug; + arr[RS::ARRAY_COLOR] = colors; RS::get_singleton()->mesh_add_surface_from_arrays(g.collision_debug, RS::PRIMITIVE_LINES, arr); - SceneTree *st = SceneTree::get_singleton(); if (st) { RS::get_singleton()->mesh_surface_set_material(g.collision_debug, 0, st->get_debug_collision_material()->get_rid()); } diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index a24745dc194..4fed916de30 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1008,15 +1008,16 @@ Ref SceneTree::get_debug_collision_material() { return collision_material; } - Ref line_material = Ref(memnew(StandardMaterial3D)); - line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); - line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - line_material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); - line_material->set_albedo(get_debug_collisions_color()); + Ref material = Ref(memnew(StandardMaterial3D)); + material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MIN + 1); + material->set_cull_mode(StandardMaterial3D::CULL_BACK); + material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); - collision_material = line_material; + collision_material = material; return collision_material; } diff --git a/scene/resources/3d/shape_3d.cpp b/scene/resources/3d/shape_3d.cpp index 4eae3ffeb2e..6f7cbdc4e43 100644 --- a/scene/resources/3d/shape_3d.cpp +++ b/scene/resources/3d/shape_3d.cpp @@ -107,36 +107,30 @@ Ref Shape3D::get_debug_mesh() { debug_mesh_cache.instantiate(); if (!lines.is_empty()) { - //make mesh - Vector array; - array.resize(lines.size()); - Vector3 *v = array.ptrw(); - - Vector arraycol; - arraycol.resize(lines.size()); - Color *c = arraycol.ptrw(); - - for (int i = 0; i < lines.size(); i++) { - v[i] = lines[i]; - c[i] = debug_color; - } + Vector colors; + colors.resize(lines.size()); + colors.fill(debug_color); Array lines_array; lines_array.resize(Mesh::ARRAY_MAX); - lines_array[Mesh::ARRAY_VERTEX] = array; - lines_array[Mesh::ARRAY_COLOR] = arraycol; - - Ref material = get_debug_collision_material(); + lines_array[Mesh::ARRAY_VERTEX] = lines; + lines_array[Mesh::ARRAY_COLOR] = colors; debug_mesh_cache->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, lines_array); - debug_mesh_cache->surface_set_material(0, material); + + SceneTree *scene_tree = SceneTree::get_singleton(); + if (scene_tree) { + debug_mesh_cache->surface_set_material(0, scene_tree->get_debug_collision_material()); + } if (debug_fill) { Ref array_mesh = get_debug_arraymesh_faces(debug_color * Color(1.0, 1.0, 1.0, 0.0625)); if (array_mesh.is_valid() && array_mesh->get_surface_count() > 0) { Array solid_array = array_mesh->surface_get_arrays(0); debug_mesh_cache->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, solid_array); - debug_mesh_cache->surface_set_material(1, material); + if (scene_tree) { + debug_mesh_cache->surface_set_material(1, scene_tree->get_debug_collision_material()); + } } } } @@ -144,26 +138,6 @@ Ref Shape3D::get_debug_mesh() { return debug_mesh_cache; } -Ref Shape3D::get_debug_collision_material() { - if (collision_material.is_valid()) { - return collision_material; - } - - Ref material = memnew(StandardMaterial3D); - material->set_albedo(Color(1.0, 1.0, 1.0)); - material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MIN + 1); - material->set_cull_mode(StandardMaterial3D::CULL_BACK); - material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); - material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); - - collision_material = material; - - return collision_material; -} - void Shape3D::_update_shape() { emit_changed(); debug_mesh_cache.unref(); diff --git a/scene/resources/3d/shape_3d.h b/scene/resources/3d/shape_3d.h index 8bf5f8d188f..cdd442ceb7f 100644 --- a/scene/resources/3d/shape_3d.h +++ b/scene/resources/3d/shape_3d.h @@ -44,7 +44,6 @@ class Shape3D : public Resource { real_t margin = 0.04; Ref debug_mesh_cache; - Ref collision_material; // Not wrapped in `#ifdef DEBUG_ENABLED` as it is used for rendering. Color debug_color = Color(0.0, 0.0, 0.0, 0.0); @@ -59,8 +58,6 @@ protected: _FORCE_INLINE_ RID get_shape() const { return shape; } Shape3D(RID p_shape); - Ref get_debug_collision_material(); - virtual void _update_shape(); public: