Repository: playcanvas/engine
File: src/scene/renderer/shadow-renderer-directional.js (JavaScript)

Code before:

            // look at the center from far away to include all casters during culling
            shadowCamNode.setPosition(center);
            shadowCamNode.translateLocal(0, 0, 1000000);
            shadowCam.nearClip = 0.01;
            shadowCam.farClip = 2000000;
            shadowCam.orthoHeight = radius;

            // cull shadow casters
            this.renderer.updateCameraFrustum(shadowCam);
            this.shadowRenderer.cullShadowCasters(comp, light, lightRenderData.visibleCasters, shadowCam, casters);

            const cascadeFlag = 1 << cascade;
            const visibleCasters = lightRenderData.visibleCasters;
            const origNumVisibleCasters = lightRenderData.visibleCasters.length;

            let numVisibleCasters = 0;

            // exclude all mesh instances that are hidden for this cascade.
            // find out AABB of visible shadow casters

            for (let i = 0; i < origNumVisibleCasters; i++) {
                const meshInstance = visibleCasters[i];
                if (meshInstance.shadowCascadeFlags & cascadeFlag) {
                    visibleCasters[numVisibleCasters++] = visibleCasters[i];
                    if (numVisibleCasters === 0) {
                        visibleSceneAabb.copy(meshInstance.aabb);
                    } else {
                        visibleSceneAabb.add(meshInstance.aabb);
                    }
                }
            }

            visibleCasters.length = numVisibleCasters;

            // calculate depth range of the caster's AABB from the point of view of the shadow camera
            shadowCamView.copy(shadowCamNode.getWorldTransform()).invert();
            const depthRange = getDepthRange(shadowCamView, visibleSceneAabb.getMin(), visibleSceneAabb.getMax());

            // adjust shadow camera's near and far plane to the depth range of casters to maximize precision
            // of values stored in the shadow map. Make it slightly larger to avoid clipping on near / far plane.
            shadowCamNode.translateLocal(0, 0, depthRange.max + 0.1);
            shadowCam.farClip = depthRange.max - depthRange.min + 0.2;

            lightRenderData.projectionCompensation = radius;
        }
    }

    // function to generate frustum split distances
    generateSplitDistances(light, nearDist, farDist) {


Review comment (suggestion):
will it ever be 0 here? there is ++ on the line before.
I'd move `numVisibleCasters++` later to make it clear.

Code after:

            // look at the center from far away to include all casters during culling
            shadowCamNode.setPosition(center);
            shadowCamNode.translateLocal(0, 0, 1000000);
            shadowCam.nearClip = 0.01;
            shadowCam.farClip = 2000000;
            shadowCam.orthoHeight = radius;

            // cull shadow casters
            this.renderer.updateCameraFrustum(shadowCam);
            this.shadowRenderer.cullShadowCasters(comp, light, lightRenderData.visibleCasters, shadowCam, casters);

            const cascadeFlag = 1 << cascade;
            const visibleCasters = lightRenderData.visibleCasters;
            const origNumVisibleCasters = visibleCasters.length;

            let numVisibleCasters = 0;

            // exclude all mesh instances that are hidden for this cascade.
            // find out AABB of visible shadow casters

            for (let i = 0; i < origNumVisibleCasters; i++) {
                const meshInstance = visibleCasters[i];
                if (meshInstance.shadowCascadeMask & cascadeFlag) {
                    visibleCasters[numVisibleCasters++] = meshInstance;
                    if (numVisibleCasters === 1) {
                        visibleSceneAabb.copy(meshInstance.aabb);
                    } else {
                        visibleSceneAabb.add(meshInstance.aabb);
                    }
                }
            }

            // remove empty tail
            if (origNumVisibleCasters !== numVisibleCasters) {
                visibleCasters.length = numVisibleCasters;
            }

            // calculate depth range of the caster's AABB from the point of view of the shadow camera
            shadowCamView.copy(shadowCamNode.getWorldTransform()).invert();
            const depthRange = getDepthRange(shadowCamView, visibleSceneAabb.getMin(), visibleSceneAabb.getMax());

            // adjust shadow camera's near and far plane to the depth range of casters to maximize precision
            // of values stored in the shadow map. Make it slightly larger to avoid clipping on near / far plane.
            shadowCamNode.translateLocal(0, 0, depthRange.max + 0.1);
            shadowCam.farClip = depthRange.max - depthRange.min + 0.2;

            lightRenderData.projectionCompensation = radius;
        }
    }