Optimize base and shadow meshes for cache
Previously, vertex cache optimization was ran for the LOD meshes, but was never ran for the base mesh or for the shadow meshes, including shadow LOD chain (shadow LOD chain would sometimes get implicitly optimized for vertex cache as a byproduct of base LOD optimization, but not always). This could significantly affect the rendering performance of geometry heavy scenes, especially for depth or shadow passes where the fragment load is light.
This commit is contained in:
parent
96be44c0ec
commit
0fde03c0e0
3 changed files with 39 additions and 0 deletions
|
@ -2544,6 +2544,8 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_
|
|||
}
|
||||
}
|
||||
|
||||
src_mesh_node->get_mesh()->optimize_indices_for_cache();
|
||||
|
||||
if (generate_lods) {
|
||||
Array skin_pose_transform_array = _get_skinned_pose_transforms(src_mesh_node);
|
||||
src_mesh_node->get_mesh()->generate_lods(merge_angle, split_angle, skin_pose_transform_array, raycast_normals);
|
||||
|
|
|
@ -256,6 +256,33 @@ void ImporterMesh::set_surface_material(int p_surface, const Ref<Material> &p_ma
|
|||
mesh.unref();
|
||||
}
|
||||
|
||||
void ImporterMesh::optimize_indices_for_cache() {
|
||||
if (!SurfaceTool::optimize_vertex_cache_func) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < surfaces.size(); i++) {
|
||||
if (surfaces[i].primitive != Mesh::PRIMITIVE_TRIANGLES) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector<Vector3> vertices = surfaces[i].arrays[RS::ARRAY_VERTEX];
|
||||
PackedInt32Array indices = surfaces[i].arrays[RS::ARRAY_INDEX];
|
||||
|
||||
unsigned int index_count = indices.size();
|
||||
unsigned int vertex_count = vertices.size();
|
||||
|
||||
if (index_count == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int *indices_ptr = indices.ptrw();
|
||||
SurfaceTool::optimize_vertex_cache_func((unsigned int *)indices_ptr, (const unsigned int *)indices_ptr, index_count, vertex_count);
|
||||
|
||||
surfaces.write[i].arrays[RS::ARRAY_INDEX] = indices;
|
||||
}
|
||||
}
|
||||
|
||||
#define VERTEX_SKIN_FUNC(bone_count, vert_idx, read_array, write_array, transform_array, bone_array, weight_array) \
|
||||
Vector3 transformed_vert; \
|
||||
for (unsigned int weight_idx = 0; weight_idx < bone_count; weight_idx++) { \
|
||||
|
@ -822,6 +849,10 @@ void ImporterMesh::create_shadow_mesh() {
|
|||
index_wptr[j] = vertex_remap[index];
|
||||
}
|
||||
|
||||
if (SurfaceTool::optimize_vertex_cache_func) {
|
||||
SurfaceTool::optimize_vertex_cache_func((unsigned int *)index_wptr, (const unsigned int *)index_wptr, index_count, new_vertices.size());
|
||||
}
|
||||
|
||||
new_surface[RS::ARRAY_INDEX] = new_indices;
|
||||
|
||||
// Make sure the same LODs as the full version are used.
|
||||
|
@ -840,6 +871,10 @@ void ImporterMesh::create_shadow_mesh() {
|
|||
index_wptr[k] = vertex_remap[index];
|
||||
}
|
||||
|
||||
if (SurfaceTool::optimize_vertex_cache_func) {
|
||||
SurfaceTool::optimize_vertex_cache_func((unsigned int *)index_wptr, (const unsigned int *)index_wptr, index_count, new_vertices.size());
|
||||
}
|
||||
|
||||
lods[surfaces[i].lods[j].distance] = new_indices;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,6 +114,8 @@ public:
|
|||
|
||||
void set_surface_material(int p_surface, const Ref<Material> &p_material);
|
||||
|
||||
void optimize_indices_for_cache();
|
||||
|
||||
void generate_lods(float p_normal_merge_angle, float p_normal_split_angle, Array p_skin_pose_transform_array, bool p_raycast_normals = false);
|
||||
|
||||
void create_shadow_mesh();
|
||||
|
|
Loading…
Reference in a new issue