Skip to content

Commit

Permalink
Merge pull request #16187 from WestLangley/dev-sh3
Browse files Browse the repository at this point in the history
Added spherical harmonics class
  • Loading branch information
WestLangley authored Apr 11, 2019
2 parents 1b587d8 + 1152066 commit 27a7280
Showing 1 changed file with 211 additions and 0 deletions.
211 changes: 211 additions & 0 deletions src/math/SphericalHarmonics3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
import { Vector3 } from './Vector3.js';

/**
* @author bhouston / http://clara.io
* @author WestLangley / http:/WestLangley
*
* Primary reference:
* https://graphics.stanford.edu/papers/envmap/envmap.pdf
*
* Secondary reference:
* https://www.ppsloan.org/publications/StupidSH36.pdf
*/

// 3-band SH defined by 9 coefficients

function SphericalHarmonics3() {

this.coefficients = [];

for ( var i = 0; i < 9; i ++ ) {

this.coefficients.push( new Vector3() );

}

}

Object.assign( SphericalHarmonics3.prototype, {

isSphericalHarmonics3: true,

set: function ( coefficients ) {

for ( var i = 0; i < 9; i ++ ) {

this.coefficients[ i ].copy( coefficients[ i ] );

}

return this;

},

zero: function () {

for ( var i = 0; i < 9; i ++ ) {

this.coefficients[ i ].set( 0, 0, 0 );

}

return this;

},

// get the radiance in the direction of the normal
// target is a Vector3
getAt: function ( normal, target ) {

// normal is assumed to be unit length

var x = normal.x, y = normal.y, z = normal.z;

var coeff = this.coefficients;

// band 0
target = coeff[ 0 ] * 0.282095;

// band 1
target += coeff[ 1 ] * 0.488603 * y;
target += coeff[ 2 ] * 0.488603 * z;
target += coeff[ 3 ] * 0.488603 * x;

// band 2
target += coeff[ 4 ] * 1.092548 * ( x * y );
target += coeff[ 5 ] * 1.092548 * ( y * z );
target += coeff[ 6 ] * 0.315392 * ( 3.0 * z * z - 1.0 );
target += coeff[ 7 ] * 1.092548 * ( x * z );
target += coeff[ 8 ] * 0.546274 * ( x * x - y * y );

return target;

},

// get the irradiance (radiance convolved with cosine lobe) in the direction of the normal
// target is a Vector3
// https://graphics.stanford.edu/papers/envmap/envmap.pdf
getIrradianceAt: function ( normal, target ) {

// normal is assumed to be unit length

var x = normal.x, y = normal.y, z = normal.z;

var coeff = this.coefficients;

// band 0
target = coeff[ 0 ] * 0.886227; // π * 0.282095

// band 1
target += coeff[ 1 ] * 2.0 * 0.511664 * y; // ( 2 * π / 3 ) * 0.488603
target += coeff[ 2 ] * 2.0 * 0.511664 * z;
target += coeff[ 3 ] * 2.0 * 0.511664 * x;

// band 2
target += coeff[ 4 ] * 2.0 * 0.429043 * x * y; // ( π / 4 ) * 1.092548
target += coeff[ 5 ] * 2.0 * 0.429043 * y * z;
target += coeff[ 6 ] * ( 0.743125 * z * z - 0.247708 ); // ( π / 4 ) * 0.315392 * 3
target += coeff[ 7 ] * 2.0 * 0.429043 * x * z;
target += coeff[ 8 ] * 0.429043 * ( x * x - y * y ); // ( π / 4 ) * 0.546274

return target;

},

add: function ( sh ) {

for ( var i = 0; i < 9; i ++ ) {

this.coefficients[ i ].add( sh.coefficients[ i ] );

}

return this;

},


scale: function ( s ) {

for ( var i = 0; i < 9; i ++ ) {

this.coefficients[ i ].multiplyScalar( s );

}

return this;

},

lerp: function ( sh, alpha ) {

for ( var i = 0; i < 9; i ++ ) {

this.coefficients[ i ].lerp( sh.coefficients[ i ], alpha );

}

return this;

},

equals: function ( sh ) {

for ( var i = 0; i < 9; i ++ ) {

if ( ! this.coefficients[ i ].equals( sh.coefficients[ i ] ) ) {

return false;

}

}

return true;

},

copy: function ( sh ) {

return this.set( sh.coefficients );

},

clone: function () {

return new this.constructor().copy( this );

}

} );

Object.assign( SphericalHarmonics3, {

// evaluate the basis functions
// shBasis is an Array[ 9 ]
getBasisAt: function ( normal, shBasis ) {

// normal is assumed to be unit length

var x = normal.x, y = normal.y, z = normal.z;

// band 0
shBasis[ 0 ] = 0.282095;

// band 1
shBasis[ 1 ] = 0.488603 * y;
shBasis[ 2 ] = 0.488603 * z;
shBasis[ 3 ] = 0.488603 * x;

// band 2
shBasis[ 4 ] = 1.092548 * x * y;
shBasis[ 5 ] = 1.092548 * y * z;
shBasis[ 6 ] = 0.315392 * ( 3 * z * z - 1 );
shBasis[ 7 ] = 1.092548 * x * z;
shBasis[ 8 ] = 0.546274 * ( x * x - y * y );

}

} );

export { SphericalHarmonics3 };

0 comments on commit 27a7280

Please sign in to comment.