|
@@ -40,6 +40,10 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
var positionVS = new THREE.Vector3();
|
|
|
var directionVS = new THREE.Vector3();
|
|
|
|
|
|
+ var direction = new THREE.Vector3();
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
var geometryLightSphere = new THREE.SphereGeometry( 1, 16, 8 );
|
|
|
var geometryLightPlane = new THREE.PlaneGeometry( 2, 2 );
|
|
|
|
|
@@ -131,7 +135,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
|
|
|
|
-
|
|
|
var createDeferredMaterials = function ( originalMaterial ) {
|
|
|
|
|
|
var deferredMaterials = {};
|
|
@@ -306,6 +309,42 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
|
|
|
|
+ var updatePointLightProxy = function ( lightProxy ) {
|
|
|
+
|
|
|
+ var light = lightProxy.properties.originalLight;
|
|
|
+ var uniforms = lightProxy.material.uniforms;
|
|
|
+
|
|
|
+ // skip infinite pointlights
|
|
|
+ // right now you can't switch between infinite and finite pointlights
|
|
|
+ // it's just too messy as they use different proxies
|
|
|
+
|
|
|
+ var distance = light.distance;
|
|
|
+
|
|
|
+ if ( distance > 0 ) {
|
|
|
+
|
|
|
+ lightProxy.scale.set( 1, 1, 1 ).multiplyScalar( distance );
|
|
|
+ uniforms[ "lightRadius" ].value = distance;
|
|
|
+
|
|
|
+ var position = light.matrixWorld.getPosition();
|
|
|
+ uniforms[ "lightPos" ].value.copy( position );
|
|
|
+
|
|
|
+ lightProxy.position.copy( position );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ uniforms[ "lightRadius" ].value = Infinity;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // linear space colors
|
|
|
+
|
|
|
+ var intensity = light.intensity * light.intensity;
|
|
|
+
|
|
|
+ uniforms[ "lightIntensity" ].value = intensity;
|
|
|
+ uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
var createDeferredPointLight = function ( light ) {
|
|
|
|
|
|
// setup light material
|
|
@@ -327,16 +366,14 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
// infinite pointlights use full-screen quad proxy
|
|
|
// regular pointlights use sphere proxy
|
|
|
|
|
|
- var distance, geometry;
|
|
|
+ var geometry;
|
|
|
|
|
|
if ( light.distance > 0 ) {
|
|
|
|
|
|
- distance = light.distance;
|
|
|
geometry = geometryLightSphere;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- distance = Infinity;
|
|
|
geometry = geometryLightPlane;
|
|
|
|
|
|
materialLight.depthTest = false;
|
|
@@ -344,16 +381,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
- // linear space
|
|
|
-
|
|
|
- var intensity = light.intensity * light.intensity;
|
|
|
- var position = light.matrixWorld.getPosition();
|
|
|
-
|
|
|
- materialLight.uniforms[ "lightPos" ].value.copy( position );
|
|
|
- materialLight.uniforms[ "lightRadius" ].value = distance;
|
|
|
- materialLight.uniforms[ "lightIntensity" ].value = intensity;
|
|
|
- materialLight.uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
|
|
|
-
|
|
|
materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
|
|
|
materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
|
|
|
|
|
@@ -364,13 +391,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
var meshLight = new THREE.Mesh( geometry, materialLight );
|
|
|
|
|
|
- if ( light.distance > 0 ) {
|
|
|
-
|
|
|
- meshLight.position.copy( position );
|
|
|
- meshLight.scale.multiplyScalar( distance );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
// keep reference for color and intensity updates
|
|
|
|
|
|
meshLight.properties.originalLight = light;
|
|
@@ -379,10 +399,42 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
resizableMaterials.push( materialLight );
|
|
|
|
|
|
+ // sync proxy uniforms to the original light
|
|
|
+
|
|
|
+ updatePointLightProxy( meshLight );
|
|
|
+
|
|
|
return meshLight;
|
|
|
|
|
|
};
|
|
|
|
|
|
+ var updateSpotLightProxy = function ( lightProxy ) {
|
|
|
+
|
|
|
+ var light = lightProxy.properties.originalLight;
|
|
|
+ var uniforms = lightProxy.material.uniforms;
|
|
|
+
|
|
|
+ positionVS.copy( light.matrixWorld.getPosition() );
|
|
|
+ camera.matrixWorldInverse.multiplyVector3( positionVS );
|
|
|
+
|
|
|
+ directionVS.copy( light.matrixWorld.getPosition() );
|
|
|
+ directionVS.subSelf( light.target.matrixWorld.getPosition() );
|
|
|
+ directionVS.normalize();
|
|
|
+ camera.matrixWorldInverse.rotateAxis( directionVS );
|
|
|
+
|
|
|
+ uniforms[ "lightPositionVS" ].value.copy( positionVS );
|
|
|
+ uniforms[ "lightDirectionVS" ].value.copy( directionVS );
|
|
|
+
|
|
|
+ uniforms[ "lightAngle" ].value = light.angle;
|
|
|
+ uniforms[ "lightDistance" ].value = light.distance;
|
|
|
+
|
|
|
+ // linear space colors
|
|
|
+
|
|
|
+ var intensity = light.intensity * light.intensity;
|
|
|
+
|
|
|
+ uniforms[ "lightIntensity" ].value = intensity;
|
|
|
+ uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
var createDeferredSpotLight = function ( light ) {
|
|
|
|
|
|
// setup light material
|
|
@@ -402,26 +454,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
} );
|
|
|
|
|
|
- // linear space
|
|
|
-
|
|
|
- var intensity = light.intensity * light.intensity;
|
|
|
-
|
|
|
- positionVS.copy( light.matrixWorld.getPosition() );
|
|
|
- camera.matrixWorldInverse.multiplyVector3( positionVS );
|
|
|
-
|
|
|
- directionVS.copy( light.matrixWorld.getPosition() );
|
|
|
- directionVS.subSelf( light.target.matrixWorld.getPosition() );
|
|
|
- directionVS.normalize();
|
|
|
- camera.matrixWorldInverse.rotateAxis( directionVS );
|
|
|
-
|
|
|
- uniforms[ "lightPositionVS" ].value.copy( positionVS );
|
|
|
- uniforms[ "lightDirectionVS" ].value.copy( directionVS );
|
|
|
-
|
|
|
- uniforms[ "lightIntensity" ].value = intensity;
|
|
|
- uniforms[ "lightAngle" ].value = light.angle;
|
|
|
- uniforms[ "lightDistance" ].value = light.distance;
|
|
|
- uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
|
|
|
-
|
|
|
uniforms[ "viewWidth" ].value = scaledWidth;
|
|
|
uniforms[ "viewHeight" ].value = scaledHeight;
|
|
|
|
|
@@ -440,17 +472,43 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
resizableMaterials.push( materialLight );
|
|
|
|
|
|
+ // sync proxy uniforms to the original light
|
|
|
+
|
|
|
+ updateSpotLightProxy( meshLight );
|
|
|
+
|
|
|
return meshLight;
|
|
|
|
|
|
};
|
|
|
|
|
|
+ var updateDirectionalLightProxy = function ( lightProxy ) {
|
|
|
+
|
|
|
+ var light = lightProxy.properties.originalLight;
|
|
|
+ var uniforms = lightProxy.material.uniforms;
|
|
|
+
|
|
|
+ direction.copy( light.matrixWorld.getPosition() );
|
|
|
+ direction.subSelf( light.target.matrixWorld.getPosition() );
|
|
|
+ direction.normalize();
|
|
|
+
|
|
|
+ uniforms[ "lightDir" ].value.copy( direction );
|
|
|
+
|
|
|
+ // linear space colors
|
|
|
+
|
|
|
+ var intensity = light.intensity * light.intensity;
|
|
|
+
|
|
|
+ uniforms[ "lightIntensity" ].value = intensity;
|
|
|
+ uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
var createDeferredDirectionalLight = function ( light ) {
|
|
|
|
|
|
// setup light material
|
|
|
|
|
|
+ var uniforms = THREE.UniformsUtils.clone( directionalLightShader.uniforms );
|
|
|
+
|
|
|
var materialLight = new THREE.ShaderMaterial( {
|
|
|
|
|
|
- uniforms: THREE.UniformsUtils.clone( directionalLightShader.uniforms ),
|
|
|
+ uniforms: uniforms,
|
|
|
vertexShader: directionalLightShader.vertexShader,
|
|
|
fragmentShader: directionalLightShader.fragmentShader,
|
|
|
|
|
@@ -461,19 +519,11 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
} );
|
|
|
|
|
|
- // linear space
|
|
|
-
|
|
|
- var intensity = light.intensity * light.intensity;
|
|
|
-
|
|
|
- materialLight.uniforms[ "lightDir" ].value = light.position;
|
|
|
- materialLight.uniforms[ "lightIntensity" ].value = intensity;
|
|
|
- materialLight.uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
|
|
|
-
|
|
|
- materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
|
|
|
- materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
|
|
|
+ uniforms[ "viewWidth" ].value = scaledWidth;
|
|
|
+ uniforms[ "viewHeight" ].value = scaledHeight;
|
|
|
|
|
|
- materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
|
|
|
- materialLight.uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
|
|
|
+ uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
|
|
|
+ uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
|
|
|
|
|
|
// create light proxy mesh
|
|
|
|
|
@@ -487,6 +537,10 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
resizableMaterials.push( materialLight );
|
|
|
|
|
|
+ // sync proxy uniforms to the original light
|
|
|
+
|
|
|
+ updateDirectionalLightProxy( meshLight );
|
|
|
+
|
|
|
return meshLight;
|
|
|
|
|
|
};
|
|
@@ -506,7 +560,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
} );
|
|
|
|
|
|
-
|
|
|
materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
|
|
|
materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
|
|
|
|
|
@@ -680,44 +733,17 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( originalLight ) {
|
|
|
|
|
|
- if ( uniforms[ "lightColor" ] ) uniforms[ "lightColor" ].value.copyGammaToLinear( originalLight.color );
|
|
|
- if ( uniforms[ "lightIntensity" ] ) uniforms[ "lightIntensity" ].value = originalLight.intensity * originalLight.intensity;
|
|
|
-
|
|
|
- lightProxy.visible = originalLight.visible;
|
|
|
-
|
|
|
if ( originalLight instanceof THREE.PointLight ) {
|
|
|
|
|
|
- var distance = originalLight.distance;
|
|
|
-
|
|
|
- // skip infinite pointlights
|
|
|
- // right now you can't switch between infinite and finite pointlights
|
|
|
- // it's just too messy as they use different proxies
|
|
|
-
|
|
|
- if ( distance > 0 ) {
|
|
|
-
|
|
|
- lightProxy.scale.set( 1, 1, 1 ).multiplyScalar( distance );
|
|
|
- if ( uniforms[ "lightRadius" ] ) uniforms[ "lightRadius" ].value = distance;
|
|
|
-
|
|
|
- var position = originalLight.matrixWorld.getPosition();
|
|
|
- uniforms[ "lightPos" ].value.copy( position );
|
|
|
-
|
|
|
- lightProxy.position.copy( position );
|
|
|
-
|
|
|
- }
|
|
|
+ updatePointLightProxy( lightProxy );
|
|
|
|
|
|
} else if ( originalLight instanceof THREE.SpotLight ) {
|
|
|
|
|
|
- positionVS.copy( originalLight.matrixWorld.getPosition() );
|
|
|
- camera.matrixWorldInverse.multiplyVector3( positionVS );
|
|
|
+ updateSpotLightProxy( lightProxy );
|
|
|
|
|
|
- directionVS.copy( originalLight.matrixWorld.getPosition() );
|
|
|
- directionVS.subSelf( originalLight.target.matrixWorld.getPosition() );
|
|
|
- directionVS.normalize();
|
|
|
- camera.matrixWorldInverse.rotateAxis( directionVS );
|
|
|
+ } else if ( originalLight instanceof THREE.DirectionalLight ) {
|
|
|
|
|
|
- uniforms[ "lightPositionVS" ].value.copy( positionVS );
|
|
|
- uniforms[ "lightDirectionVS" ].value.copy( directionVS );
|
|
|
- uniforms[ "lightAngle" ].value = originalLight.angle;
|
|
|
+ updateDirectionalLightProxy( lightProxy );
|
|
|
|
|
|
}
|
|
|
|