Skip to content

Commit 0dc6cc1

Browse files
kzhswsebavan
andauthored
ShadowGenerator: optimize renderList parsing in Parse (#17034)
The `ShadowGenerator.Parse` method exhibited a performance bottleneck due to its inefficient handling of the `renderList`. Previously, it iterated through the `parsedShadowGenerator.renderList` and for each mesh ID, it called `scene.getMeshesById`. This resulted in an O(m*n) time complexity, where 'n' is the total number of meshes in the scene and 'm' is the number of meshes in the `renderList`. Profiling indicated that `getMeshesById` was a significant performance drain. This commit refactors the parsing logic to improve efficiency. Instead of repeatedly querying meshes by ID, it now creates a `Set` of mesh IDs from the `renderList` (O(m) time and space). It then iterates through all meshes in the scene once (O(n) time) and checks for membership in the `Set` using an O(1) average time complexity lookup. Any mesh whose ID is found in the set is added to the `shadowMap.renderList`. This change reduces the overall time complexity of parsing the `renderList` to O(n + m), which is a substantial performance improvement, especially for scenes with a large number of meshes or a large `renderList`. Forum post: <https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086> --------- Co-authored-by: sebavan <[email protected]>
1 parent 1d8a17d commit 0dc6cc1

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

packages/dev/core/src/Lights/Shadows/shadowGenerator.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,16 +2155,17 @@ export class ShadowGenerator implements IShadowGenerator {
21552155
const shadowGenerator = constr ? constr(parsedShadowGenerator.mapSize, light, camera) : new ShadowGenerator(parsedShadowGenerator.mapSize, light, undefined, camera);
21562156
const shadowMap = shadowGenerator.getShadowMap();
21572157

2158-
for (let meshIndex = 0; meshIndex < parsedShadowGenerator.renderList.length; meshIndex++) {
2159-
const meshes = scene.getMeshesById(parsedShadowGenerator.renderList[meshIndex]);
2158+
if (parsedShadowGenerator.renderList.length && shadowMap) {
2159+
const renderSet = new Set<string>(parsedShadowGenerator.renderList);
2160+
let renderList = shadowMap.renderList;
2161+
if (!renderList) {
2162+
renderList = shadowMap.renderList = [];
2163+
}
2164+
const meshes = scene.meshes;
21602165
for (const mesh of meshes) {
2161-
if (!shadowMap) {
2162-
continue;
2163-
}
2164-
if (!shadowMap.renderList) {
2165-
shadowMap.renderList = [];
2166+
if (renderSet.has(mesh.id)) {
2167+
renderList.push(mesh);
21662168
}
2167-
shadowMap.renderList.push(mesh);
21682169
}
21692170
}
21702171

0 commit comments

Comments
 (0)