Skip to content

Commit

Permalink
Merge pull request #18735 from gkjohnson/csm-breaks-cache-arrays
Browse files Browse the repository at this point in the history
CSM: Remove array allocation in getBreaks, getExtendedBreaks
  • Loading branch information
mrdoob authored Feb 27, 2020
2 parents 7ea3b62 + 3e937e9 commit 2324c89
Showing 1 changed file with 35 additions and 40 deletions.
75 changes: 35 additions & 40 deletions examples/jsm/csm/CSM.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const _lightSpaceFrustum = new Frustum();
const _frustum = new Frustum();
const _center = new Vector3();
const _bbox = new FrustumBoundingBox();
const _uniformArray = [];
const _logArray = [];

export default class CSM {

Expand All @@ -46,6 +48,7 @@ export default class CSM {
this.customSplitsCallback = data.customSplitsCallback;
this.mainFrustum = new Frustum();
this.frustums = [];
this.breaks = [];

this.lights = [];
this.materials = [];
Expand Down Expand Up @@ -92,70 +95,64 @@ export default class CSM {

const camera = this.camera;
const far = Math.min(camera.far, this.maxFar);
this.breaks = [];
this.breaks.length = 0;

switch ( this.mode ) {

case 'uniform':
this.breaks = uniformSplit( this.cascades, camera.near, far );
uniformSplit( this.cascades, camera.near, far, this.breaks );
break;
case 'logarithmic':
this.breaks = logarithmicSplit( this.cascades, camera.near, far );
logarithmicSplit( this.cascades, camera.near, far, this.breaks );
break;
case 'practical':
this.breaks = practicalSplit( this.cascades, camera.near, far, 0.5 );
practicalSplit( this.cascades, camera.near, far, 0.5, this.breaks );
break;
case 'custom':
if ( this.customSplitsCallback === undefined ) console.error( 'CSM: Custom split scheme callback not defined.' );
this.breaks = this.customSplitsCallback( this.cascades, camera.near, far );
this.customSplitsCallback( this.cascades, camera.near, far, this.breaks );
break;

}

function uniformSplit( amount, near, far ) {

const r = [];
function uniformSplit( amount, near, far, target ) {

for ( let i = 1; i < amount; i ++ ) {

r.push( ( near + ( far - near ) * i / amount ) / far );
target.push( ( near + ( far - near ) * i / amount ) / far );

}

r.push( 1 );
return r;
target.push( 1 );

}

function logarithmicSplit( amount, near, far ) {

const r = [];
function logarithmicSplit( amount, near, far, target ) {

for ( let i = 1; i < amount; i ++ ) {

r.push( ( near * ( far / near ) ** ( i / amount ) ) / far );
target.push( ( near * ( far / near ) ** ( i / amount ) ) / far );

}

r.push( 1 );
return r;
target.push( 1 );

}

function practicalSplit( amount, near, far, lambda ) {
function practicalSplit( amount, near, far, lambda, target ) {

const log = logarithmicSplit( amount, near, far );
const uni = uniformSplit( amount, near, far );
const r = [];
_uniformArray.length = 0;
_logArray.length = 0;
const log = logarithmicSplit( amount, near, far, _logArray );
const uni = uniformSplit( amount, near, far, _uniformArray );

for ( let i = 1; i < amount; i ++ ) {

r.push( MathUtils.lerp( uni[ i - 1 ], log[ i - 1 ], lambda ) );
target.push( MathUtils.lerp( _uniformArray[ i - 1 ], _logArray[ i - 1 ], lambda ) );

}

r.push( 1 );
return r;
target.push( 1 );

}

Expand Down Expand Up @@ -213,14 +210,7 @@ export default class CSM {
material.defines.CSM_CASCADES = this.cascades;

const breaksVec2 = [];

for ( let i = 0; i < this.cascades; i ++ ) {

let amount = this.breaks[ i ];
let prev = this.breaks[ i - 1 ] || 0;
breaksVec2.push( new Vector2( prev, amount ) );

}
this.getExtendedBreaks( breaksVec2 );

const self = this;
const far = Math.min(this.camera.far, this.maxFar);
Expand All @@ -243,28 +233,33 @@ export default class CSM {

for ( let i = 0; i < this.materials.length; i ++ ) {

this.materials[ i ].uniforms.CSM_cascades.value = this.getExtendedBreaks();
this.materials[ i ].uniforms.cameraNear.value = this.camera.near;
this.materials[ i ].uniforms.shadowFar.value = far;
const uniforms = this.materials[ i ].uniforms;
this.getExtendedBreaks( uniforms.CSM_cascades.value );
uniforms.cameraNear.value = this.camera.near;
uniforms.shadowFar.value = far;

}

}

getExtendedBreaks() {
getExtendedBreaks( target ) {

while ( target.length < this.breaks.length ) {

let breaksVec2 = [];
target.push( new Vector2() );

}
target.length = this.breaks.length;

for ( let i = 0; i < this.cascades; i ++ ) {

let amount = this.breaks[ i ];
let prev = this.breaks[ i - 1 ] || 0;
breaksVec2.push( new Vector2( prev, amount ) );
target[ i ].x = prev;
target[ i ].y = amount;

}

return breaksVec2;

}

updateFrustums() {
Expand Down

0 comments on commit 2324c89

Please sign in to comment.