Browse Source

WebGLDeferredRenderer: fixed crashing on infinite distance PointLights.

Nevertheless these are very heavy in deferred shading because they need to touch every pixel.

Try to avoid using infinite distance PointLights, always specify some light.distance (smaller the better, more local light is cheaper it is).
alteredq 12 years ago
parent
commit
cbad8416a4
1 changed files with 44 additions and 10 deletions
  1. 44 10
      examples/js/renderers/WebGLDeferredRenderer.js

+ 44 - 10
examples/js/renderers/WebGLDeferredRenderer.js

@@ -36,7 +36,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 	//
 
-	var geometryLight = new THREE.SphereGeometry( 1, 16, 8 );
+	var geometryLightSphere = new THREE.SphereGeometry( 1, 16, 8 );
+	var geometryLightPlane = new THREE.PlaneGeometry( 2, 2 );
 
 	var black = new THREE.Color( 0x000000 );
 
@@ -285,8 +286,28 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		} );
 
+		// infinite pointlights use full-screen quad proxy
+		// regular pointlights use sphere proxy
+
+		var distance, geometry;
+
+		if ( light.distance > 0 ) {
+
+			distance = light.distance;
+			geometry = geometryLightSphere;
+
+		} else {
+
+			distance = Infinity;
+			geometry = geometryLightPlane;
+
+			materialLight.depthTest = false;
+			materialLight.side = THREE.FrontSide;
+
+		}
+
 		materialLight.uniforms[ "lightPos" ].value = light.position;
-		materialLight.uniforms[ "lightRadius" ].value = light.distance;
+		materialLight.uniforms[ "lightRadius" ].value = distance;
 		materialLight.uniforms[ "lightIntensity" ].value = light.intensity;
 		materialLight.uniforms[ "lightColor" ].value = light.color;
 
@@ -298,9 +319,14 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		// create light proxy mesh
 
-		var meshLight = new THREE.Mesh( geometryLight, materialLight );
-		meshLight.position = light.position;
-		meshLight.scale.multiplyScalar( light.distance );
+		var meshLight = new THREE.Mesh( geometry, materialLight );
+
+		if ( light.distance > 0 ) {
+
+			meshLight.position = light.position;
+			meshLight.scale.multiplyScalar( distance );
+
+		}
 
 		// keep reference for size reset
 
@@ -338,8 +364,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		// create light proxy mesh
 
-		var geometryLight = new THREE.PlaneGeometry( 2, 2 );
-		var meshLight = new THREE.Mesh( geometryLight, materialLight );
+		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
 
 		// keep reference for size reset
 
@@ -372,8 +397,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		// create light proxy mesh
 
-		var geometryLight = new THREE.PlaneGeometry( 2, 2 );
-		var meshLight = new THREE.Mesh( geometryLight, materialLight );
+		var meshLight = new THREE.Mesh( geometryLightPlane, materialLight );
 
 		// keep reference for size reset
 
@@ -392,7 +416,16 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		if ( object instanceof THREE.PointLight ) {
 
 			var meshLight = createDeferredPointLight( object );
-			lightSceneProxy.add( meshLight );
+
+			if ( object.distance > 0 ) {
+
+				lightSceneProxy.add( meshLight );
+
+			} else {
+
+				lightSceneFullscreen.add( meshLight );
+
+			}
 
 		} else if ( object instanceof THREE.DirectionalLight ) {
 
@@ -554,6 +587,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 			var uniforms = lightSceneFullscreen.children[ i ].material.uniforms;
 
+			if ( uniforms[ "matProjInverse" ] ) uniforms[ "matProjInverse" ].value = camera.projectionMatrixInverse;
 			if ( uniforms[ "matView" ] ) uniforms[ "matView" ].value = camera.matrixWorldInverse;
 
 		}