Browse Source

WebGLDeferredRenderer: optimized area lights computation.

Moved computation of view space position, normal and right vectors out of shader into JS and passing them as per-light uniforms.
alteredq 12 years ago
parent
commit
83136c5dad
2 changed files with 41 additions and 46 deletions
  1. 18 32
      examples/js/ShaderDeferred.js
  2. 23 14
      examples/js/renderers/WebGLDeferredRenderer.js

+ 18 - 32
examples/js/ShaderDeferred.js

@@ -831,17 +831,16 @@ THREE.ShaderDeferred = {
 			samplerNormalDepth: { type: "t", value: null },
 			samplerColor: 		{ type: "t", value: null },
 			matProjInverse: { type: "m4", value: new THREE.Matrix4() },
-			matView: 		{ type: "m4", value: new THREE.Matrix4() },
 			viewWidth: 		{ type: "f", value: 800 },
 			viewHeight: 	{ type: "f", value: 600 },
 
-			lightPosition:  { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
+			lightPositionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
+			lightNormalVS: 	 { type: "v3", value: new THREE.Vector3( 0, -1, 0 ) },
+			lightRightVS:  	 { type: "v3", value: new THREE.Vector3( 1, 0, 0 ) },
+
 			lightColor: 	{ type: "c", value: new THREE.Color( 0x000000 ) },
 			lightIntensity: { type: "f", value: 1.0 },
 
-			lightRight:  { type: "v3", value: new THREE.Vector3( 1, 0, 0 ) },
-			lightNormal: { type: "v3", value: new THREE.Vector3( 0, -1, 0 ) },
-
 			lightWidth: { type: "f", value: 1.0 },
 			lightHeight: { type: "f", value: 1.0 }
 
@@ -849,9 +848,9 @@ THREE.ShaderDeferred = {
 
 		fragmentShader : [
 
-			"varying vec3 lightPosVS;",
-			"varying vec3 lightNormalVS;",
-			"varying vec3 lightRightVS;",
+			"uniform vec3 lightPositionVS;",
+			"uniform vec3 lightNormalVS;",
+			"uniform vec3 lightRightVS;",
 
 			"uniform sampler2D samplerColor;",
 			"uniform sampler2D samplerNormalDepth;",
@@ -906,12 +905,12 @@ THREE.ShaderDeferred = {
 				"float h = lightHeight;",
 
 				"vec3 lightUpVS = normalize( cross( lightRightVS, lightNormalVS ) );",
-				"vec3 proj = projectOnPlane( vertexPositionVS.xyz, lightPosVS, lightNormalVS );",
-				"vec3 dir = proj - lightPosVS;",
+				"vec3 proj = projectOnPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS );",
+				"vec3 dir = proj - lightPositionVS;",
 
 				"vec2 diagonal = vec2( dot( dir, lightRightVS ), dot( dir, lightUpVS ) );",
 				"vec2 nearest2D = vec2( clamp( diagonal.x, -w, w ), clamp( diagonal.y, -h, h ) );",
-				"vec3 nearestPointInside = vec3( lightPosVS ) + ( lightRightVS * nearest2D.x + lightUpVS * nearest2D.y );",
+				"vec3 nearestPointInside = vec3( lightPositionVS ) + ( lightRightVS * nearest2D.x + lightUpVS * nearest2D.y );",
 
 				"float dist = distance( vertexPositionVS.xyz, nearestPointInside );",
 				"float attenuation = calculateAttenuation( dist );",
@@ -921,44 +920,31 @@ THREE.ShaderDeferred = {
 
 				"float NdotL = dot( lightNormalVS, -lightDir );",
 
-				"if ( NdotL != 0.0 && sideOfPlane( vertexPositionVS.xyz, lightPosVS, lightNormalVS ) ) {",
+				"if ( NdotL != 0.0 && sideOfPlane( vertexPositionVS.xyz, lightPositionVS, lightNormalVS ) ) {",
 
 					"color.xyz = vec3( lightColor * attenuation * NdotL * 1.5 );",
 
+					"gl_FragColor = vec4( color, 1.0 );",
+
 				"} else {",
 
-					"color.xyz = vec3( 0.0 );",
+					"discard;",
 
 				"}",
 
-				"gl_FragColor = vec4( color, 1.0 );",
-
 			"}"
 
 		].join("\n"),
 
 		vertexShader : [
 
-		"varying vec3 lightPosVS;",
-		"varying vec3 lightNormalVS;",
-		"varying vec3 lightRightVS;",
-
-		"uniform vec3 lightPosition;",
-		"uniform vec3 lightNormal;",
-		"uniform vec3 lightRight;",
-
-		"uniform mat4 matView;",
-
-		"void main() {",
+			"void main() {",
 
-			"vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );",
-			"gl_Position = pos;",
+				// full screen quad proxy
 
-			"lightNormalVS = normalize( mat3( matView ) * lightNormal );",
-			"lightRightVS = normalize( mat3( matView ) * lightRight ); ",
-			"lightPosVS = vec3( matView * vec4( lightPosition, 1.0 ) );",
+				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
 
-		 "}"
+			"}"
 
 		].join("\n")
 

+ 23 - 14
examples/js/renderers/WebGLDeferredRenderer.js

@@ -40,8 +40,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	var positionVS = new THREE.Vector3();
 	var directionVS = new THREE.Vector3();
 
-	var right = new THREE.Vector3();
-	var normal = new THREE.Vector3();
+	var rightVS = new THREE.Vector3();
+	var normalVS = new THREE.Vector3();
 
 	//
 
@@ -416,13 +416,16 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		var light = lightProxy.properties.originalLight;
 		var uniforms = lightProxy.material.uniforms;
 
-		positionVS.copy( light.matrixWorld.getPosition() );
-		camera.matrixWorldInverse.multiplyVector3( positionVS );
+		var viewMatrix = camera.matrixWorldInverse;
+		var modelMatrix = light.matrixWorld;
 
-		directionVS.copy( light.matrixWorld.getPosition() );
+		positionVS.copy( modelMatrix.getPosition() );
+		viewMatrix.multiplyVector3( positionVS );
+
+		directionVS.copy( modelMatrix.getPosition() );
 		directionVS.subSelf( light.target.matrixWorld.getPosition() );
 		directionVS.normalize();
-		camera.matrixWorldInverse.rotateAxis( directionVS );
+		viewMatrix.rotateAxis( directionVS );
 
 		uniforms[ "lightPositionVS" ].value.copy( positionVS );
 		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
@@ -621,17 +624,23 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		var light = lightProxy.properties.originalLight;
 		var uniforms = lightProxy.material.uniforms;
 
-		uniforms[ "lightPosition" ].value.copy( light.matrixWorld.getPosition() );
+		var modelMatrix = light.matrixWorld;
+		var viewMatrix = camera.matrixWorldInverse;
+
+		positionVS.copy( modelMatrix.getPosition() );
+		viewMatrix.multiplyVector3( positionVS );
+		uniforms[ "lightPositionVS" ].value.copy( positionVS );
 
-		var matrix = light.matrixWorld;
+		rightVS.copy( light.right );
+		normalVS.copy( light.normal );
+		modelMatrix.rotateAxis( rightVS );
+		modelMatrix.rotateAxis( normalVS );
 
-		right.copy( light.right );
-		normal.copy( light.normal );
-		matrix.rotateAxis( right );
-		matrix.rotateAxis( normal );
+		viewMatrix.rotateAxis( rightVS );
+		viewMatrix.rotateAxis( normalVS );
 
-		uniforms[ "lightRight" ].value.copy( right );
-		uniforms[ "lightNormal" ].value.copy( normal );
+		uniforms[ "lightRightVS" ].value.copy( rightVS );
+		uniforms[ "lightNormalVS" ].value.copy( normalVS );
 
 		uniforms[ "lightWidth" ].value = light.width;
 		uniforms[ "lightHeight" ].value = light.height;