Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/src/Three.js b/src/Three.js
- index 86c86576d..86ca48939 100644
- --- a/src/Three.js
- +++ b/src/Three.js
- @@ -48,8 +48,8 @@ export { Loader } from './loaders/Loader.js';
- export { Cache } from './loaders/Cache.js';
- export { AudioLoader } from './loaders/AudioLoader.js';
- export { SpotLightShadow } from './lights/SpotLightShadow.js';
- -export { SpotLight } from './lights/SpotLight.js';
- -export { PointLight } from './lights/PointLight.js';
- +export { LODPointLight as PointLight } from './lights/LODPointLight.js';
- +export { LODSpotLight as SpotLight } from './lights/LODSpotLight.js';
- export { RectAreaLight } from './lights/RectAreaLight.js';
- export { HemisphereLight } from './lights/HemisphereLight.js';
- export { DirectionalLightShadow } from './lights/DirectionalLightShadow.js';
- diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js
- index 09dcd7589..c779874de 100644
- --- a/src/renderers/WebGLRenderer.js
- +++ b/src/renderers/WebGLRenderer.js
- @@ -36,6 +36,8 @@ import { WebGLClipping } from './webgl/WebGLClipping';
- import { Frustum } from '../math/Frustum';
- import { Vector4 } from '../math/Vector4';
- import { Color } from '../math/Color';
- +import { PointLight } from '../lights/PointLight';
- +import { SpotLight } from '../lights/SpotLight';
- /**
- * @author supereggbert / http://www.paulbrunt.co.uk/
- @@ -185,6 +187,8 @@ function WebGLRenderer( parameters ) {
- pointShadowMap: [],
- pointShadowMatrix: [],
- hemi: [],
- + LODPoint: [],
- + LODSpot: [],
- shadows: []
- @@ -1035,7 +1039,7 @@ function WebGLRenderer( parameters ) {
- // Compile
- this.compile = function ( scene, camera ) {
- -
- +
- lights = [];
- scene.traverse( function ( object ) {
- @@ -1048,6 +1052,8 @@ function WebGLRenderer( parameters ) {
- } );
- + replaceLODLights( lights, scene, camera );
- +
- setupLights( lights, camera );
- scene.traverse( function ( object ) {
- @@ -1130,6 +1136,8 @@ function WebGLRenderer( parameters ) {
- if ( _clippingEnabled ) _clipping.beginShadows();
- + replaceLODLights( lights, scene, camera );
- +
- setupShadows( lights );
- shadowMap.render( scene, camera );
- @@ -1634,6 +1642,8 @@ function WebGLRenderer( parameters ) {
- uniforms.rectAreaLights.value = _lights.rectArea;
- uniforms.pointLights.value = _lights.point;
- uniforms.hemisphereLights.value = _lights.hemi;
- + uniforms.LODPointLights.value = _lights.LODPoint;
- + uniforms.LODSpotLights.value = _lights.LODSpot;
- uniforms.directionalShadowMap.value = _lights.directionalShadowMap;
- uniforms.directionalShadowMatrix.value = _lights.directionalShadowMatrix;
- @@ -2278,11 +2288,135 @@ function WebGLRenderer( parameters ) {
- uniforms.spotLights.needsUpdate = value;
- uniforms.rectAreaLights.needsUpdate = value;
- uniforms.hemisphereLights.needsUpdate = value;
- + uniforms.LODPointLights.needsUpdate = value;
- + uniforms.LODSpotLights.needsUpdate = value;
- }
- // Lighting
- + var MAX_TOTAL = 125, //not sure how to determine this programmatically
- + MAX_LOCAL = 16, //nor this, given lights are probably not the only textures required. I guess these should be set optimistically low, and then presented as a user option?
- + LOCAL_LIGHTS = [], //cache
- + PRIORITY_LIGHT_TYPES = /DirectionalLight|AmbientLight|HemisphereLight|RectAreaLight|^PointLight$|^SpotLight$/,//all Lights that are outside of our localized system here
- + UNLOD_LIGHT_TYPES = /DirectionalLight/; //Only lights that will have shadows we aren't controlling. RectAreaLight needs to be added here when it has shadows, presumably.
- +
- + function depthSort( objectsArray, camera ) {
- +
- + return objectsArray.sort((a, b) => {
- + var aMatch = a.type.match(PRIORITY_LIGHT_TYPES),
- + bMatch = b.type.match(PRIORITY_LIGHT_TYPES);
- +
- + if( aMatch && !bMatch ) return -1;
- + if( bMatch && !aMatch ) return 1;
- +
- + return a.position.distanceTo(camera.position) - b.position.distanceTo(camera.position)
- + })
- +
- + }
- +
- +
- + function countUnLODLights( lights ) {
- +
- + var dir = 0, light;
- +
- + for ( var i = 0, l = lights.length; i < l; i++ ) {
- +
- + light = lights[ i ];
- +
- + if ( light.type.match(UNLOD_LIGHT_TYPES) ) {
- +
- + dir ++;
- +
- + }
- +
- + }
- +
- + return dir;
- +
- + }
- +
- +
- + function getGrossLights( lights ) {
- +
- + var gross = 0, light;
- +
- + for ( var i = 0, l = lights.length; i < l; i++ ) {
- +
- + light = lights[i];
- +
- + if ( light.type.match(PRIORITY_LIGHT_TYPES) ) {
- +
- + gross ++;
- +
- + }
- +
- + }
- +
- + return gross;
- +
- + }
- +
- + function replaceLODLights( lights, scene, camera ) {
- +
- + depthSort( lights, camera );
- +
- +
- + var light;
- +
- +
- + for ( var i = 0, l = lights.length, p = 0, m = MAX_LOCAL - countUnLODLights( lights ); i < l && p < m; i++ ) {
- +
- + light = lights[ i ];
- +
- + if ( light.castShadow ) {
- +
- + var isPoint = light.isLODPointLight;
- +
- + if ( isPoint || light.isLODSpotLight ) {
- +
- +
- + if ( !LOCAL_LIGHTS[ p ] || isPoint !== LOCAL_LIGHTS[ p ].isPointLight ) {
- +
- + LOCAL_LIGHTS[ p ] = isPoint? new PointLight() : new SpotLight();
- +
- + LOCAL_LIGHTS[ p ].castShadow = true;
- +
- + }
- +
- + var local = LOCAL_LIGHTS[ p ];
- +
- + local.color = light.color;
- + local.position.copy( light.position );
- +
- + local.distance = light.distance;
- + local.decay = light.decay;
- + local.intensity = light.intensity;
- +
- + if ( !isPoint ) {
- +
- + local.angle = light.angle;
- + local.penumbra = light.penumbra;
- + local.target = light.target;
- +
- + }
- +
- + local.updateMatrix();
- + local.updateMatrixWorld(true);
- +
- + lights[ i ] = LOCAL_LIGHTS[ p ];
- +
- + p ++;
- + }
- +
- + }
- +
- + }
- +
- + return lights;
- +
- + }
- +
- function setupShadows( lights ) {
- var lightShadowsLength = 0;
- @@ -2291,7 +2425,7 @@ function WebGLRenderer( parameters ) {
- var light = lights[ i ];
- - if ( light.castShadow ) {
- + if ( light.castShadow && !( light.isLODPointLight || light.isLODSpotLight ) ) {
- _lights.shadows[ lightShadowsLength ] = light;
- lightShadowsLength ++;
- @@ -2319,7 +2453,12 @@ function WebGLRenderer( parameters ) {
- pointLength = 0,
- spotLength = 0,
- rectAreaLength = 0,
- - hemiLength = 0;
- + hemiLength = 0,
- +
- + p = 0,
- + m = MAX_TOTAL - getGrossLights( lights ),
- + LODPointLength = 0,
- + LODSpotLength = 0;
- for ( l = 0, ll = lights.length; l < ll; l ++ ) {
- @@ -2480,6 +2619,46 @@ function WebGLRenderer( parameters ) {
- hemiLength ++;
- + } else if ( light.isLODPointLight && p < m ) {
- +
- + var uniforms = lightCache.get( light );
- +
- + uniforms.position.setFromMatrixPosition( light.matrixWorld );
- + uniforms.position.applyMatrix4( viewMatrix );
- +
- + uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
- + uniforms.distance = light.distance;
- + uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
- +
- + _lights.LODPoint[ LODPointLength ] = uniforms;
- +
- + LODPointLength ++;
- + p ++;
- +
- + } else if ( light.isLODSpotLight && p < m ) {
- +
- + var uniforms = lightCache.get( light );
- +
- + uniforms.position.setFromMatrixPosition( light.matrixWorld );
- + uniforms.position.applyMatrix4( viewMatrix );
- +
- + uniforms.color.copy( color ).multiplyScalar( intensity );
- + uniforms.distance = distance;
- +
- + uniforms.direction.setFromMatrixPosition( light.matrixWorld );
- + _vector3.setFromMatrixPosition( light.target.matrixWorld );
- + uniforms.direction.sub( _vector3 );
- + uniforms.direction.transformDirection( viewMatrix );
- +
- + uniforms.coneCos = Math.cos( light.angle );
- + uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
- + uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
- +
- + _lights.LODSpot[ LODSpotLength ] = uniforms;
- +
- + LODSpotLength ++;
- + p ++;
- +
- }
- }
- @@ -2494,8 +2673,11 @@ function WebGLRenderer( parameters ) {
- _lights.point.length = pointLength;
- _lights.hemi.length = hemiLength;
- + _lights.LODPoint.length = LODPointLength;
- + _lights.LODSpot.length = LODSpotLength;
- +
- // TODO (sam-g-steel) why aren't we using join
- - _lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + _lights.shadows.length;
- + _lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + LODPointLength + ',' + LODSpotLength + ',' + _lights.shadows.length;
- }
- diff --git a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl
- index cd50e0362..3a9e6dce5 100644
- --- a/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl
- +++ b/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl
- @@ -61,6 +61,47 @@ vec3 directLightColor_Diffuse;
- #endif
- +#if NUM_LOD_POINT_LIGHTS > 0
- +
- + for ( int i = 0; i < NUM_LOD_POINT_LIGHTS; i ++ ) {
- +
- + getLODPointDirectLightIrradiance( LODPointLights[ i ], geometry, directLight );
- +
- + dotNL = dot( geometry.normal, directLight.direction );
- + directLightColor_Diffuse = PI * directLight.color;
- +
- + vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
- +
- + #ifdef DOUBLE_SIDED
- +
- + vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;
- +
- + #endif
- +
- + }
- +
- +#endif
- +
- +#if NUM_LOD_SPOT_LIGHTS > 0
- +
- + for ( int i = 0; i < NUM_LOD_SPOT_LIGHTS; i ++ ) {
- +
- + getLODSpotDirectLightIrradiance( LODSpotLights[ i ], geometry, directLight );
- +
- + dotNL = dot( geometry.normal, directLight.direction );
- + directLightColor_Diffuse = PI * directLight.color;
- +
- + vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
- +
- + #ifdef DOUBLE_SIDED
- +
- + vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;
- +
- + #endif
- + }
- +
- +#endif
- +
- /*
- #if NUM_RECT_AREA_LIGHTS > 0
- diff --git a/src/renderers/shaders/ShaderChunk/lights_pars.glsl b/src/renderers/shaders/ShaderChunk/lights_pars.glsl
- index 6bb83b281..a56999215 100644
- --- a/src/renderers/shaders/ShaderChunk/lights_pars.glsl
- +++ b/src/renderers/shaders/ShaderChunk/lights_pars.glsl
- @@ -167,6 +167,73 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
- #endif
- +#if NUM_LOD_POINT_LIGHTS > 0
- +
- + struct LODPointLight {
- + vec3 position;
- + vec3 color;
- + float distance;
- + float decay;
- + };
- +
- + uniform LODPointLight LODPointLights[ NUM_LOD_POINT_LIGHTS ];
- +
- + // directLight is an out parameter as having it as a return value caused compiler errors on some devices
- + void getLODPointDirectLightIrradiance( const in LODPointLight lodPointLight, const in GeometricContext geometry, out IncidentLight directLight ) {
- +
- + vec3 lVector = lodPointLight.position - geometry.position;
- + directLight.direction = normalize( lVector );
- +
- + float lightDistance = length( lVector );
- +
- + directLight.color = lodPointLight.color;
- + directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, lodPointLight.distance, lodPointLight.decay );
- + directLight.visible = ( directLight.color != vec3( 0.0 ) );
- +
- + }
- +
- +#endif
- +
- +#if NUM_LOD_SPOT_LIGHTS > 0
- +
- + struct LODSpotLight {
- + vec3 position;
- + vec3 direction;
- + vec3 color;
- + float distance;
- + float decay;
- + float coneCos;
- + float penumbraCos;
- + };
- +
- + uniform LODSpotLight LODSpotLights[ NUM_LOD_SPOT_LIGHTS ];
- +
- + // directLight is an out parameter as having it as a return value caused compiler errors on some devices
- + void getLODSpotDirectLightIrradiance( const in LODSpotLight lodSpotLight, const in GeometricContext geometry, out IncidentLight directLight ) {
- +
- + vec3 lVector = lodSpotLight.position - geometry.position;
- + directLight.direction = normalize( lVector );
- +
- + float lightDistance = length( lVector );
- + float angleCos = dot( directLight.direction, lodSpotLight.direction );
- +
- + if ( angleCos > lodSpotLight.coneCos ) {
- +
- + float spotEffect = smoothstep( lodSpotLight.coneCos, lodSpotLight.penumbraCos, angleCos );
- +
- + directLight.color = lodSpotLight.color;
- + directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, lodSpotLight.distance, lodSpotLight.decay );
- + directLight.visible = true;
- +
- + } else {
- +
- + directLight.color = vec3( 0.0 );
- + directLight.visible = false;
- +
- + }
- + }
- +
- +#endif
- #if defined( USE_ENVMAP ) && defined( PHYSICAL )
- diff --git a/src/renderers/shaders/ShaderChunk/lights_template.glsl b/src/renderers/shaders/ShaderChunk/lights_template.glsl
- index 219e7956e..e5bf24d69 100644
- --- a/src/renderers/shaders/ShaderChunk/lights_template.glsl
- +++ b/src/renderers/shaders/ShaderChunk/lights_template.glsl
- @@ -94,6 +94,38 @@ IncidentLight directLight;
- #endif
- +#if ( NUM_LOD_POINT_LIGHTS > 0 ) && defined( RE_Direct )
- +
- + LODPointLight lodPointLight;
- +
- + for ( int i = 0; i < NUM_LOD_POINT_LIGHTS; i ++ ) {
- +
- + lodPointLight = LODPointLights[ i ];
- +
- + getLODPointDirectLightIrradiance( lodPointLight, geometry, directLight );
- +
- + RE_Direct( directLight, geometry, material, reflectedLight );
- +
- + }
- +
- +#endif
- +
- +#if ( NUM_LOD_SPOT_LIGHTS > 0 ) && defined( RE_Direct )
- +
- + LODSpotLight lodSpotLight;
- +
- + for ( int i = 0; i < NUM_LOD_SPOT_LIGHTS; i ++ ) {
- +
- + lodSpotLight = LODSpotLights[ i ];
- +
- + getLODSpotDirectLightIrradiance( lodSpotLight, geometry, directLight );
- +
- + RE_Direct( directLight, geometry, material, reflectedLight );
- +
- + }
- +
- +#endif
- +
- #if defined( RE_IndirectDiffuse )
- vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );
- diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js
- index 3dc12e2a5..5fdd64ae9 100644
- --- a/src/renderers/shaders/UniformsLib.js
- +++ b/src/renderers/shaders/UniformsLib.js
- @@ -128,6 +128,16 @@ var UniformsLib = {
- shadowMapSize: {}
- } },
- + LODSpotLights: { value: [], properties: {
- + color: {},
- + position: {},
- + direction: {},
- + distance: {},
- + coneCos: {},
- + penumbraCos: {},
- + decay: {}
- + } },
- +
- spotShadowMap: { value: [] },
- spotShadowMatrix: { value: [] },
- @@ -143,6 +153,13 @@ var UniformsLib = {
- shadowMapSize: {}
- } },
- + LODPointLights: { value: [], properties: {
- + color: {},
- + position: {},
- + decay: {},
- + distance: {}
- + } },
- +
- pointShadowMap: { value: [] },
- pointShadowMatrix: { value: [] },
- diff --git a/src/renderers/webgl/WebGLLights.js b/src/renderers/webgl/WebGLLights.js
- index 1ef409578..757cb3b84 100644
- --- a/src/renderers/webgl/WebGLLights.js
- +++ b/src/renderers/webgl/WebGLLights.js
- @@ -85,6 +85,27 @@ function WebGLLights() {
- };
- break;
- + case 'LODPointLight':
- + uniforms = {
- + position: new Vector3(),
- + color: new Color(),
- + distance: 0,
- + decay: 0
- + };
- + break;
- +
- + case 'LODSpotLight':
- + uniforms = {
- + position: new Vector3(),
- + direction: new Vector3(),
- + color: new Color(),
- + distance: 0,
- + coneCos: 0,
- + penumbraCos: 0,
- + decay: 0
- + };
- + break;
- +
- }
- lights[ light.id ] = uniforms;
- diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
- index 30c6e8b08..931a2c276 100644
- --- a/src/renderers/webgl/WebGLProgram.js
- +++ b/src/renderers/webgl/WebGLProgram.js
- @@ -146,7 +146,9 @@ function replaceLightNums( string, parameters ) {
- .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
- .replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )
- .replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
- - .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );
- + .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights )
- + .replace( /NUM_LOD_POINT_LIGHTS/g, parameters.numLODPointLights )
- + .replace( /NUM_LOD_SPOT_LIGHTS/g, parameters.numLODSpotLights );
- }
- diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js
- index d07e65e33..89553b1ce 100644
- --- a/src/renderers/webgl/WebGLPrograms.js
- +++ b/src/renderers/webgl/WebGLPrograms.js
- @@ -32,6 +32,7 @@ function WebGLPrograms( renderer, capabilities ) {
- "maxBones", "useVertexTexture", "morphTargets", "morphNormals",
- "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
- "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
- + "numLODPointLights", "numLODSpotLights",
- "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
- "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering"
- ];
- @@ -126,7 +127,7 @@ function WebGLPrograms( renderer, capabilities ) {
- }
- var currentRenderTarget = renderer.getRenderTarget();
- -
- +
- var parameters = {
- shaderID: shaderID,
- @@ -181,6 +182,8 @@ function WebGLPrograms( renderer, capabilities ) {
- numSpotLights: lights.spot.length,
- numRectAreaLights: lights.rectArea.length,
- numHemiLights: lights.hemi.length,
- + numLODPointLights: lights.LODPoint.length,
- + numLODSpotLights: lights.LODSpot.length,
- numClippingPlanes: nClipPlanes,
- numClipIntersection: nClipIntersection,
Advertisement
Add Comment
Please, Sign In to add comment