📄 WebGLLights.js
¶
📊 Analysis Summary¶
Metric | Count |
---|---|
🔧 Functions | 10 |
📦 Imports | 5 |
📊 Variables & Constants | 45 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 src/renderers/webgl/WebGLLights.js
📦 Imports¶
Name | Source |
---|---|
Color |
../../math/Color.js |
Matrix4 |
../../math/Matrix4.js |
Vector2 |
../../math/Vector2.js |
Vector3 |
../../math/Vector3.js |
UniformsLib |
../shaders/UniformsLib.js |
Variables & Constants¶
Name | Type | Kind | Value | Exported |
---|---|---|---|---|
lights |
{} |
let/var | {} |
✗ |
uniforms |
any |
let/var | *not shown* |
✗ |
lights |
{} |
let/var | {} |
✗ |
uniforms |
any |
let/var | *not shown* |
✗ |
nextVersion |
number |
let/var | 0 |
✗ |
cache |
any |
let/var | new UniformsCache() |
✗ |
state |
{ version: number; hash: { directiona... |
let/var | { version: 0, hash: { directionalLength: - 1, pointLength: - 1, spotLength: -... |
✗ |
vector3 |
Vector3 |
let/var | new Vector3() |
✗ |
matrix4 |
Matrix4 |
let/var | new Matrix4() |
✗ |
matrix42 |
Matrix4 |
let/var | new Matrix4() |
✗ |
r |
number |
let/var | 0 |
✗ |
g |
number |
let/var | 0 |
✗ |
b |
number |
let/var | 0 |
✗ |
directionalLength |
number |
let/var | 0 |
✗ |
pointLength |
number |
let/var | 0 |
✗ |
spotLength |
number |
let/var | 0 |
✗ |
rectAreaLength |
number |
let/var | 0 |
✗ |
hemiLength |
number |
let/var | 0 |
✗ |
numDirectionalShadows |
number |
let/var | 0 |
✗ |
numPointShadows |
number |
let/var | 0 |
✗ |
numSpotShadows |
number |
let/var | 0 |
✗ |
numSpotMaps |
number |
let/var | 0 |
✗ |
numSpotShadowsWithMaps |
number |
let/var | 0 |
✗ |
numLightProbes |
number |
let/var | 0 |
✗ |
light |
any |
let/var | lights[ i ] |
✗ |
color |
any |
let/var | light.color |
✗ |
intensity |
any |
let/var | light.intensity |
✗ |
distance |
any |
let/var | light.distance |
✗ |
shadowMap |
any |
let/var | ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null |
✗ |
shadow |
any |
let/var | light.shadow |
✗ |
shadow |
any |
let/var | light.shadow |
✗ |
shadow |
any |
let/var | light.shadow |
✗ |
hash |
{ directionalLength: number; pointLen... |
let/var | state.hash |
✗ |
directionalLength |
number |
let/var | 0 |
✗ |
pointLength |
number |
let/var | 0 |
✗ |
spotLength |
number |
let/var | 0 |
✗ |
rectAreaLength |
number |
let/var | 0 |
✗ |
hemiLength |
number |
let/var | 0 |
✗ |
viewMatrix |
any |
let/var | camera.matrixWorldInverse |
✗ |
light |
any |
let/var | lights[ i ] |
✗ |
uniforms |
any |
let/var | state.directional[ directionalLength ] |
✗ |
uniforms |
any |
let/var | state.spot[ spotLength ] |
✗ |
uniforms |
any |
let/var | state.rectArea[ rectAreaLength ] |
✗ |
uniforms |
any |
let/var | state.point[ pointLength ] |
✗ |
uniforms |
any |
let/var | state.hemi[ hemiLength ] |
✗ |
Functions¶
UniformsCache(): { get: (light: any) => any; }
¶
Returns: { get: (light: any) => any; }
Code
function UniformsCache() {
const lights = {};
return {
get: function ( light ) {
if ( lights[ light.id ] !== undefined ) {
return lights[ light.id ];
}
let uniforms;
switch ( light.type ) {
case 'DirectionalLight':
uniforms = {
direction: new Vector3(),
color: new Color()
};
break;
case 'SpotLight':
uniforms = {
position: new Vector3(),
direction: new Vector3(),
color: new Color(),
distance: 0,
coneCos: 0,
penumbraCos: 0,
decay: 0
};
break;
case 'PointLight':
uniforms = {
position: new Vector3(),
color: new Color(),
distance: 0,
decay: 0
};
break;
case 'HemisphereLight':
uniforms = {
direction: new Vector3(),
skyColor: new Color(),
groundColor: new Color()
};
break;
case 'RectAreaLight':
uniforms = {
color: new Color(),
position: new Vector3(),
halfWidth: new Vector3(),
halfHeight: new Vector3()
};
break;
}
lights[ light.id ] = uniforms;
return uniforms;
}
};
}
get(light: any): any
¶
Parameters:
light
any
Returns: any
Code
function ( light ) {
if ( lights[ light.id ] !== undefined ) {
return lights[ light.id ];
}
let uniforms;
switch ( light.type ) {
case 'DirectionalLight':
uniforms = {
direction: new Vector3(),
color: new Color()
};
break;
case 'SpotLight':
uniforms = {
position: new Vector3(),
direction: new Vector3(),
color: new Color(),
distance: 0,
coneCos: 0,
penumbraCos: 0,
decay: 0
};
break;
case 'PointLight':
uniforms = {
position: new Vector3(),
color: new Color(),
distance: 0,
decay: 0
};
break;
case 'HemisphereLight':
uniforms = {
direction: new Vector3(),
skyColor: new Color(),
groundColor: new Color()
};
break;
case 'RectAreaLight':
uniforms = {
color: new Color(),
position: new Vector3(),
halfWidth: new Vector3(),
halfHeight: new Vector3()
};
break;
}
lights[ light.id ] = uniforms;
return uniforms;
}
get(light: any): any
¶
Parameters:
light
any
Returns: any
Code
function ( light ) {
if ( lights[ light.id ] !== undefined ) {
return lights[ light.id ];
}
let uniforms;
switch ( light.type ) {
case 'DirectionalLight':
uniforms = {
direction: new Vector3(),
color: new Color()
};
break;
case 'SpotLight':
uniforms = {
position: new Vector3(),
direction: new Vector3(),
color: new Color(),
distance: 0,
coneCos: 0,
penumbraCos: 0,
decay: 0
};
break;
case 'PointLight':
uniforms = {
position: new Vector3(),
color: new Color(),
distance: 0,
decay: 0
};
break;
case 'HemisphereLight':
uniforms = {
direction: new Vector3(),
skyColor: new Color(),
groundColor: new Color()
};
break;
case 'RectAreaLight':
uniforms = {
color: new Color(),
position: new Vector3(),
halfWidth: new Vector3(),
halfHeight: new Vector3()
};
break;
}
lights[ light.id ] = uniforms;
return uniforms;
}
ShadowUniformsCache(): { get: (light: any) => any; }
¶
Returns: { get: (light: any) => any; }
Code
function ShadowUniformsCache() {
const lights = {};
return {
get: function ( light ) {
if ( lights[ light.id ] !== undefined ) {
return lights[ light.id ];
}
let uniforms;
switch ( light.type ) {
case 'DirectionalLight':
uniforms = {
shadowIntensity: 1,
shadowBias: 0,
shadowNormalBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
};
break;
case 'SpotLight':
uniforms = {
shadowIntensity: 1,
shadowBias: 0,
shadowNormalBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
};
break;
case 'PointLight':
uniforms = {
shadowIntensity: 1,
shadowBias: 0,
shadowNormalBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2(),
shadowCameraNear: 1,
shadowCameraFar: 1000
};
break;
// TODO (abelnation): set RectAreaLight shadow uniforms
}
lights[ light.id ] = uniforms;
return uniforms;
}
};
}
get(light: any): any
¶
Parameters:
light
any
Returns: any
Code
function ( light ) {
if ( lights[ light.id ] !== undefined ) {
return lights[ light.id ];
}
let uniforms;
switch ( light.type ) {
case 'DirectionalLight':
uniforms = {
shadowIntensity: 1,
shadowBias: 0,
shadowNormalBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
};
break;
case 'SpotLight':
uniforms = {
shadowIntensity: 1,
shadowBias: 0,
shadowNormalBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
};
break;
case 'PointLight':
uniforms = {
shadowIntensity: 1,
shadowBias: 0,
shadowNormalBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2(),
shadowCameraNear: 1,
shadowCameraFar: 1000
};
break;
// TODO (abelnation): set RectAreaLight shadow uniforms
}
lights[ light.id ] = uniforms;
return uniforms;
}
get(light: any): any
¶
Parameters:
light
any
Returns: any
Code
function ( light ) {
if ( lights[ light.id ] !== undefined ) {
return lights[ light.id ];
}
let uniforms;
switch ( light.type ) {
case 'DirectionalLight':
uniforms = {
shadowIntensity: 1,
shadowBias: 0,
shadowNormalBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
};
break;
case 'SpotLight':
uniforms = {
shadowIntensity: 1,
shadowBias: 0,
shadowNormalBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2()
};
break;
case 'PointLight':
uniforms = {
shadowIntensity: 1,
shadowBias: 0,
shadowNormalBias: 0,
shadowRadius: 1,
shadowMapSize: new Vector2(),
shadowCameraNear: 1,
shadowCameraFar: 1000
};
break;
// TODO (abelnation): set RectAreaLight shadow uniforms
}
lights[ light.id ] = uniforms;
return uniforms;
}
shadowCastingAndTexturingLightsFirst(lightA: any, lightB: any): number
¶
Parameters:
lightA
any
lightB
any
Returns: number
Code
WebGLLights(extensions: any): { setup: (lights: any) => void; setupView: (lights: any, camera: any) => void; state: { version: number; hash: { directionalLength: number; pointLength: number; spotLength: number; rectAreaLength: number; ... 5 more ...; numLightProbes: number; }; ... 20 more ...; numLightProbes: number; }; }
¶
Parameters:
extensions
any
Returns: { setup: (lights: any) => void; setupView: (lights: any, camera: any) => void; state: { version: number; hash: { directionalLength: number; pointLength: number; spotLength: number; rectAreaLength: number; ... 5 more ...; numLightProbes: number; }; ... 20 more ...; numLightProbes: number; }; }
Calls:
ShadowUniformsCache
state.probe.push
state.probe[ i ].set
lights.sort
state.probe[ j ].addScaledVector
cache.get
uniforms.color.copy( light.color ).multiplyScalar
shadowCache.get
uniforms.position.setFromMatrixPosition
uniforms.color.copy( color ).multiplyScalar
Math.cos
shadow.updateMatrices
uniforms.halfWidth.set
uniforms.halfHeight.set
uniforms.skyColor.copy( light.color ).multiplyScalar
uniforms.groundColor.copy( light.groundColor ).multiplyScalar
extensions.has
uniforms.direction.setFromMatrixPosition
vector3.setFromMatrixPosition
uniforms.direction.sub
uniforms.direction.transformDirection
uniforms.position.applyMatrix4
matrix42.identity
matrix4.copy
matrix4.premultiply
matrix42.extractRotation
uniforms.halfWidth.applyMatrix4
uniforms.halfHeight.applyMatrix4
Internal Comments:
// ordering : [shadow casting + map texturing, map texturing, shadow casting, none ] (x4)
// make sure the lightMatrix is up to date (x4)
// TODO : do it if required only (x4)
// extract local rotation of light to derive width/height half vectors (x4)
Code
function WebGLLights( extensions ) {
const cache = new UniformsCache();
const shadowCache = ShadowUniformsCache();
const state = {
version: 0,
hash: {
directionalLength: - 1,
pointLength: - 1,
spotLength: - 1,
rectAreaLength: - 1,
hemiLength: - 1,
numDirectionalShadows: - 1,
numPointShadows: - 1,
numSpotShadows: - 1,
numSpotMaps: - 1,
numLightProbes: - 1
},
ambient: [ 0, 0, 0 ],
probe: [],
directional: [],
directionalShadow: [],
directionalShadowMap: [],
directionalShadowMatrix: [],
spot: [],
spotLightMap: [],
spotShadow: [],
spotShadowMap: [],
spotLightMatrix: [],
rectArea: [],
rectAreaLTC1: null,
rectAreaLTC2: null,
point: [],
pointShadow: [],
pointShadowMap: [],
pointShadowMatrix: [],
hemi: [],
numSpotLightShadowsWithMaps: 0,
numLightProbes: 0
};
for ( let i = 0; i < 9; i ++ ) state.probe.push( new Vector3() );
const vector3 = new Vector3();
const matrix4 = new Matrix4();
const matrix42 = new Matrix4();
function setup( lights ) {
let r = 0, g = 0, b = 0;
for ( let i = 0; i < 9; i ++ ) state.probe[ i ].set( 0, 0, 0 );
let directionalLength = 0;
let pointLength = 0;
let spotLength = 0;
let rectAreaLength = 0;
let hemiLength = 0;
let numDirectionalShadows = 0;
let numPointShadows = 0;
let numSpotShadows = 0;
let numSpotMaps = 0;
let numSpotShadowsWithMaps = 0;
let numLightProbes = 0;
// ordering : [shadow casting + map texturing, map texturing, shadow casting, none ]
lights.sort( shadowCastingAndTexturingLightsFirst );
for ( let i = 0, l = lights.length; i < l; i ++ ) {
const light = lights[ i ];
const color = light.color;
const intensity = light.intensity;
const distance = light.distance;
const shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
if ( light.isAmbientLight ) {
r += color.r * intensity;
g += color.g * intensity;
b += color.b * intensity;
} else if ( light.isLightProbe ) {
for ( let j = 0; j < 9; j ++ ) {
state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity );
}
numLightProbes ++;
} else if ( light.isDirectionalLight ) {
const uniforms = cache.get( light );
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
if ( light.castShadow ) {
const shadow = light.shadow;
const shadowUniforms = shadowCache.get( light );
shadowUniforms.shadowIntensity = shadow.intensity;
shadowUniforms.shadowBias = shadow.bias;
shadowUniforms.shadowNormalBias = shadow.normalBias;
shadowUniforms.shadowRadius = shadow.radius;
shadowUniforms.shadowMapSize = shadow.mapSize;
state.directionalShadow[ directionalLength ] = shadowUniforms;
state.directionalShadowMap[ directionalLength ] = shadowMap;
state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
numDirectionalShadows ++;
}
state.directional[ directionalLength ] = uniforms;
directionalLength ++;
} else if ( light.isSpotLight ) {
const uniforms = cache.get( light );
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.color.copy( color ).multiplyScalar( intensity );
uniforms.distance = distance;
uniforms.coneCos = Math.cos( light.angle );
uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
uniforms.decay = light.decay;
state.spot[ spotLength ] = uniforms;
const shadow = light.shadow;
if ( light.map ) {
state.spotLightMap[ numSpotMaps ] = light.map;
numSpotMaps ++;
// make sure the lightMatrix is up to date
// TODO : do it if required only
shadow.updateMatrices( light );
if ( light.castShadow ) numSpotShadowsWithMaps ++;
}
state.spotLightMatrix[ spotLength ] = shadow.matrix;
if ( light.castShadow ) {
const shadowUniforms = shadowCache.get( light );
shadowUniforms.shadowIntensity = shadow.intensity;
shadowUniforms.shadowBias = shadow.bias;
shadowUniforms.shadowNormalBias = shadow.normalBias;
shadowUniforms.shadowRadius = shadow.radius;
shadowUniforms.shadowMapSize = shadow.mapSize;
state.spotShadow[ spotLength ] = shadowUniforms;
state.spotShadowMap[ spotLength ] = shadowMap;
numSpotShadows ++;
}
spotLength ++;
} else if ( light.isRectAreaLight ) {
const uniforms = cache.get( light );
uniforms.color.copy( color ).multiplyScalar( intensity );
uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
state.rectArea[ rectAreaLength ] = uniforms;
rectAreaLength ++;
} else if ( light.isPointLight ) {
const uniforms = cache.get( light );
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
uniforms.distance = light.distance;
uniforms.decay = light.decay;
if ( light.castShadow ) {
const shadow = light.shadow;
const shadowUniforms = shadowCache.get( light );
shadowUniforms.shadowIntensity = shadow.intensity;
shadowUniforms.shadowBias = shadow.bias;
shadowUniforms.shadowNormalBias = shadow.normalBias;
shadowUniforms.shadowRadius = shadow.radius;
shadowUniforms.shadowMapSize = shadow.mapSize;
shadowUniforms.shadowCameraNear = shadow.camera.near;
shadowUniforms.shadowCameraFar = shadow.camera.far;
state.pointShadow[ pointLength ] = shadowUniforms;
state.pointShadowMap[ pointLength ] = shadowMap;
state.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
numPointShadows ++;
}
state.point[ pointLength ] = uniforms;
pointLength ++;
} else if ( light.isHemisphereLight ) {
const uniforms = cache.get( light );
uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
state.hemi[ hemiLength ] = uniforms;
hemiLength ++;
}
}
if ( rectAreaLength > 0 ) {
if ( extensions.has( 'OES_texture_float_linear' ) === true ) {
state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
} else {
state.rectAreaLTC1 = UniformsLib.LTC_HALF_1;
state.rectAreaLTC2 = UniformsLib.LTC_HALF_2;
}
}
state.ambient[ 0 ] = r;
state.ambient[ 1 ] = g;
state.ambient[ 2 ] = b;
const hash = state.hash;
if ( hash.directionalLength !== directionalLength ||
hash.pointLength !== pointLength ||
hash.spotLength !== spotLength ||
hash.rectAreaLength !== rectAreaLength ||
hash.hemiLength !== hemiLength ||
hash.numDirectionalShadows !== numDirectionalShadows ||
hash.numPointShadows !== numPointShadows ||
hash.numSpotShadows !== numSpotShadows ||
hash.numSpotMaps !== numSpotMaps ||
hash.numLightProbes !== numLightProbes ) {
state.directional.length = directionalLength;
state.spot.length = spotLength;
state.rectArea.length = rectAreaLength;
state.point.length = pointLength;
state.hemi.length = hemiLength;
state.directionalShadow.length = numDirectionalShadows;
state.directionalShadowMap.length = numDirectionalShadows;
state.pointShadow.length = numPointShadows;
state.pointShadowMap.length = numPointShadows;
state.spotShadow.length = numSpotShadows;
state.spotShadowMap.length = numSpotShadows;
state.directionalShadowMatrix.length = numDirectionalShadows;
state.pointShadowMatrix.length = numPointShadows;
state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps;
state.spotLightMap.length = numSpotMaps;
state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps;
state.numLightProbes = numLightProbes;
hash.directionalLength = directionalLength;
hash.pointLength = pointLength;
hash.spotLength = spotLength;
hash.rectAreaLength = rectAreaLength;
hash.hemiLength = hemiLength;
hash.numDirectionalShadows = numDirectionalShadows;
hash.numPointShadows = numPointShadows;
hash.numSpotShadows = numSpotShadows;
hash.numSpotMaps = numSpotMaps;
hash.numLightProbes = numLightProbes;
state.version = nextVersion ++;
}
}
function setupView( lights, camera ) {
let directionalLength = 0;
let pointLength = 0;
let spotLength = 0;
let rectAreaLength = 0;
let hemiLength = 0;
const viewMatrix = camera.matrixWorldInverse;
for ( let i = 0, l = lights.length; i < l; i ++ ) {
const light = lights[ i ];
if ( light.isDirectionalLight ) {
const uniforms = state.directional[ directionalLength ];
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
vector3.setFromMatrixPosition( light.target.matrixWorld );
uniforms.direction.sub( vector3 );
uniforms.direction.transformDirection( viewMatrix );
directionalLength ++;
} else if ( light.isSpotLight ) {
const uniforms = state.spot[ spotLength ];
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
vector3.setFromMatrixPosition( light.target.matrixWorld );
uniforms.direction.sub( vector3 );
uniforms.direction.transformDirection( viewMatrix );
spotLength ++;
} else if ( light.isRectAreaLight ) {
const uniforms = state.rectArea[ rectAreaLength ];
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
// extract local rotation of light to derive width/height half vectors
matrix42.identity();
matrix4.copy( light.matrixWorld );
matrix4.premultiply( viewMatrix );
matrix42.extractRotation( matrix4 );
uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
uniforms.halfWidth.applyMatrix4( matrix42 );
uniforms.halfHeight.applyMatrix4( matrix42 );
rectAreaLength ++;
} else if ( light.isPointLight ) {
const uniforms = state.point[ pointLength ];
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
pointLength ++;
} else if ( light.isHemisphereLight ) {
const uniforms = state.hemi[ hemiLength ];
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
uniforms.direction.transformDirection( viewMatrix );
hemiLength ++;
}
}
}
return {
setup: setup,
setupView: setupView,
state: state
};
}
setup(lights: any): void
¶
Parameters:
lights
any
Returns: void
Calls:
state.probe[ i ].set
lights.sort
state.probe[ j ].addScaledVector
cache.get
uniforms.color.copy( light.color ).multiplyScalar
shadowCache.get
uniforms.position.setFromMatrixPosition
uniforms.color.copy( color ).multiplyScalar
Math.cos
shadow.updateMatrices
uniforms.halfWidth.set
uniforms.halfHeight.set
uniforms.skyColor.copy( light.color ).multiplyScalar
uniforms.groundColor.copy( light.groundColor ).multiplyScalar
extensions.has
Internal Comments:
// ordering : [shadow casting + map texturing, map texturing, shadow casting, none ] (x4)
// make sure the lightMatrix is up to date (x4)
// TODO : do it if required only (x4)
Code
function setup( lights ) {
let r = 0, g = 0, b = 0;
for ( let i = 0; i < 9; i ++ ) state.probe[ i ].set( 0, 0, 0 );
let directionalLength = 0;
let pointLength = 0;
let spotLength = 0;
let rectAreaLength = 0;
let hemiLength = 0;
let numDirectionalShadows = 0;
let numPointShadows = 0;
let numSpotShadows = 0;
let numSpotMaps = 0;
let numSpotShadowsWithMaps = 0;
let numLightProbes = 0;
// ordering : [shadow casting + map texturing, map texturing, shadow casting, none ]
lights.sort( shadowCastingAndTexturingLightsFirst );
for ( let i = 0, l = lights.length; i < l; i ++ ) {
const light = lights[ i ];
const color = light.color;
const intensity = light.intensity;
const distance = light.distance;
const shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
if ( light.isAmbientLight ) {
r += color.r * intensity;
g += color.g * intensity;
b += color.b * intensity;
} else if ( light.isLightProbe ) {
for ( let j = 0; j < 9; j ++ ) {
state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity );
}
numLightProbes ++;
} else if ( light.isDirectionalLight ) {
const uniforms = cache.get( light );
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
if ( light.castShadow ) {
const shadow = light.shadow;
const shadowUniforms = shadowCache.get( light );
shadowUniforms.shadowIntensity = shadow.intensity;
shadowUniforms.shadowBias = shadow.bias;
shadowUniforms.shadowNormalBias = shadow.normalBias;
shadowUniforms.shadowRadius = shadow.radius;
shadowUniforms.shadowMapSize = shadow.mapSize;
state.directionalShadow[ directionalLength ] = shadowUniforms;
state.directionalShadowMap[ directionalLength ] = shadowMap;
state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
numDirectionalShadows ++;
}
state.directional[ directionalLength ] = uniforms;
directionalLength ++;
} else if ( light.isSpotLight ) {
const uniforms = cache.get( light );
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.color.copy( color ).multiplyScalar( intensity );
uniforms.distance = distance;
uniforms.coneCos = Math.cos( light.angle );
uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
uniforms.decay = light.decay;
state.spot[ spotLength ] = uniforms;
const shadow = light.shadow;
if ( light.map ) {
state.spotLightMap[ numSpotMaps ] = light.map;
numSpotMaps ++;
// make sure the lightMatrix is up to date
// TODO : do it if required only
shadow.updateMatrices( light );
if ( light.castShadow ) numSpotShadowsWithMaps ++;
}
state.spotLightMatrix[ spotLength ] = shadow.matrix;
if ( light.castShadow ) {
const shadowUniforms = shadowCache.get( light );
shadowUniforms.shadowIntensity = shadow.intensity;
shadowUniforms.shadowBias = shadow.bias;
shadowUniforms.shadowNormalBias = shadow.normalBias;
shadowUniforms.shadowRadius = shadow.radius;
shadowUniforms.shadowMapSize = shadow.mapSize;
state.spotShadow[ spotLength ] = shadowUniforms;
state.spotShadowMap[ spotLength ] = shadowMap;
numSpotShadows ++;
}
spotLength ++;
} else if ( light.isRectAreaLight ) {
const uniforms = cache.get( light );
uniforms.color.copy( color ).multiplyScalar( intensity );
uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
state.rectArea[ rectAreaLength ] = uniforms;
rectAreaLength ++;
} else if ( light.isPointLight ) {
const uniforms = cache.get( light );
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
uniforms.distance = light.distance;
uniforms.decay = light.decay;
if ( light.castShadow ) {
const shadow = light.shadow;
const shadowUniforms = shadowCache.get( light );
shadowUniforms.shadowIntensity = shadow.intensity;
shadowUniforms.shadowBias = shadow.bias;
shadowUniforms.shadowNormalBias = shadow.normalBias;
shadowUniforms.shadowRadius = shadow.radius;
shadowUniforms.shadowMapSize = shadow.mapSize;
shadowUniforms.shadowCameraNear = shadow.camera.near;
shadowUniforms.shadowCameraFar = shadow.camera.far;
state.pointShadow[ pointLength ] = shadowUniforms;
state.pointShadowMap[ pointLength ] = shadowMap;
state.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
numPointShadows ++;
}
state.point[ pointLength ] = uniforms;
pointLength ++;
} else if ( light.isHemisphereLight ) {
const uniforms = cache.get( light );
uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
state.hemi[ hemiLength ] = uniforms;
hemiLength ++;
}
}
if ( rectAreaLength > 0 ) {
if ( extensions.has( 'OES_texture_float_linear' ) === true ) {
state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
} else {
state.rectAreaLTC1 = UniformsLib.LTC_HALF_1;
state.rectAreaLTC2 = UniformsLib.LTC_HALF_2;
}
}
state.ambient[ 0 ] = r;
state.ambient[ 1 ] = g;
state.ambient[ 2 ] = b;
const hash = state.hash;
if ( hash.directionalLength !== directionalLength ||
hash.pointLength !== pointLength ||
hash.spotLength !== spotLength ||
hash.rectAreaLength !== rectAreaLength ||
hash.hemiLength !== hemiLength ||
hash.numDirectionalShadows !== numDirectionalShadows ||
hash.numPointShadows !== numPointShadows ||
hash.numSpotShadows !== numSpotShadows ||
hash.numSpotMaps !== numSpotMaps ||
hash.numLightProbes !== numLightProbes ) {
state.directional.length = directionalLength;
state.spot.length = spotLength;
state.rectArea.length = rectAreaLength;
state.point.length = pointLength;
state.hemi.length = hemiLength;
state.directionalShadow.length = numDirectionalShadows;
state.directionalShadowMap.length = numDirectionalShadows;
state.pointShadow.length = numPointShadows;
state.pointShadowMap.length = numPointShadows;
state.spotShadow.length = numSpotShadows;
state.spotShadowMap.length = numSpotShadows;
state.directionalShadowMatrix.length = numDirectionalShadows;
state.pointShadowMatrix.length = numPointShadows;
state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps;
state.spotLightMap.length = numSpotMaps;
state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps;
state.numLightProbes = numLightProbes;
hash.directionalLength = directionalLength;
hash.pointLength = pointLength;
hash.spotLength = spotLength;
hash.rectAreaLength = rectAreaLength;
hash.hemiLength = hemiLength;
hash.numDirectionalShadows = numDirectionalShadows;
hash.numPointShadows = numPointShadows;
hash.numSpotShadows = numSpotShadows;
hash.numSpotMaps = numSpotMaps;
hash.numLightProbes = numLightProbes;
state.version = nextVersion ++;
}
}
setupView(lights: any, camera: any): void
¶
Parameters:
lights
any
camera
any
Returns: void
Calls:
uniforms.direction.setFromMatrixPosition
vector3.setFromMatrixPosition
uniforms.direction.sub
uniforms.direction.transformDirection
uniforms.position.setFromMatrixPosition
uniforms.position.applyMatrix4
matrix42.identity
matrix4.copy
matrix4.premultiply
matrix42.extractRotation
uniforms.halfWidth.set
uniforms.halfHeight.set
uniforms.halfWidth.applyMatrix4
uniforms.halfHeight.applyMatrix4
Internal Comments:
Code
function setupView( lights, camera ) {
let directionalLength = 0;
let pointLength = 0;
let spotLength = 0;
let rectAreaLength = 0;
let hemiLength = 0;
const viewMatrix = camera.matrixWorldInverse;
for ( let i = 0, l = lights.length; i < l; i ++ ) {
const light = lights[ i ];
if ( light.isDirectionalLight ) {
const uniforms = state.directional[ directionalLength ];
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
vector3.setFromMatrixPosition( light.target.matrixWorld );
uniforms.direction.sub( vector3 );
uniforms.direction.transformDirection( viewMatrix );
directionalLength ++;
} else if ( light.isSpotLight ) {
const uniforms = state.spot[ spotLength ];
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
vector3.setFromMatrixPosition( light.target.matrixWorld );
uniforms.direction.sub( vector3 );
uniforms.direction.transformDirection( viewMatrix );
spotLength ++;
} else if ( light.isRectAreaLight ) {
const uniforms = state.rectArea[ rectAreaLength ];
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
// extract local rotation of light to derive width/height half vectors
matrix42.identity();
matrix4.copy( light.matrixWorld );
matrix4.premultiply( viewMatrix );
matrix42.extractRotation( matrix4 );
uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
uniforms.halfWidth.applyMatrix4( matrix42 );
uniforms.halfHeight.applyMatrix4( matrix42 );
rectAreaLength ++;
} else if ( light.isPointLight ) {
const uniforms = state.point[ pointLength ];
uniforms.position.setFromMatrixPosition( light.matrixWorld );
uniforms.position.applyMatrix4( viewMatrix );
pointLength ++;
} else if ( light.isHemisphereLight ) {
const uniforms = state.hemi[ hemiLength ];
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
uniforms.direction.transformDirection( viewMatrix );
hemiLength ++;
}
}
}