Buckets:
ktongue/docker_container / simsite /frontend /node_modules /three /src /renderers /webgl /WebGLLights.js
| import { Color } from '../../math/Color.js'; | |
| import { Matrix4 } from '../../math/Matrix4.js'; | |
| import { Vector2 } from '../../math/Vector2.js'; | |
| import { Vector3 } from '../../math/Vector3.js'; | |
| import { UniformsLib } from '../shaders/UniformsLib.js'; | |
| 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; | |
| } | |
| }; | |
| } | |
| 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 = { | |
| shadowBias: 0, | |
| shadowNormalBias: 0, | |
| shadowRadius: 1, | |
| shadowMapSize: new Vector2() | |
| }; | |
| break; | |
| case 'SpotLight': | |
| uniforms = { | |
| shadowBias: 0, | |
| shadowNormalBias: 0, | |
| shadowRadius: 1, | |
| shadowMapSize: new Vector2() | |
| }; | |
| break; | |
| case 'PointLight': | |
| uniforms = { | |
| 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; | |
| } | |
| }; | |
| } | |
| let nextVersion = 0; | |
| function shadowCastingAndTexturingLightsFirst( lightA, lightB ) { | |
| return ( lightB.castShadow ? 2 : 0 ) - ( lightA.castShadow ? 2 : 0 ) + ( lightB.map ? 1 : 0 ) - ( lightA.map ? 1 : 0 ); | |
| } | |
| function WebGLLights( extensions, capabilities ) { | |
| 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, useLegacyLights ) { | |
| 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 ); | |
| // artist-friendly light intensity scaling factor | |
| const scaleFactor = ( useLegacyLights === true ) ? Math.PI : 1; | |
| 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 * scaleFactor; | |
| g += color.g * intensity * scaleFactor; | |
| b += color.b * intensity * scaleFactor; | |
| } 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 * scaleFactor ); | |
| if ( light.castShadow ) { | |
| const shadow = light.shadow; | |
| const shadowUniforms = shadowCache.get( light ); | |
| 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 * scaleFactor ); | |
| 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.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 * scaleFactor ); | |
| uniforms.distance = light.distance; | |
| uniforms.decay = light.decay; | |
| if ( light.castShadow ) { | |
| const shadow = light.shadow; | |
| const shadowUniforms = shadowCache.get( light ); | |
| 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 * scaleFactor ); | |
| uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity * scaleFactor ); | |
| state.hemi[ hemiLength ] = uniforms; | |
| hemiLength ++; | |
| } | |
| } | |
| if ( rectAreaLength > 0 ) { | |
| if ( capabilities.isWebGL2 ) { | |
| // WebGL 2 | |
| 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; | |
| } | |
| } else { | |
| // WebGL 1 | |
| if ( extensions.has( 'OES_texture_float_linear' ) === true ) { | |
| state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1; | |
| state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2; | |
| } else if ( extensions.has( 'OES_texture_half_float_linear' ) === true ) { | |
| state.rectAreaLTC1 = UniformsLib.LTC_HALF_1; | |
| state.rectAreaLTC2 = UniformsLib.LTC_HALF_2; | |
| } else { | |
| console.error( 'THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.' ); | |
| } | |
| } | |
| } | |
| 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 | |
| }; | |
| } | |
| export { WebGLLights }; | |
Xet Storage Details
- Size:
- 13.8 kB
- Xet hash:
- 121cdc2e388c4a056b78ecce3e7dd84cda8293bbd689d73deb5c12f2f361cf9b
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.