Browse Source

WebGLDeferredRenderer: more refactoring of deferred shaders.

More code chunks sharing and naming unification. This should make easier to add new light types and to modify lights features.
alteredq 12 years ago
parent
commit
e04c17e0ea
1 changed files with 69 additions and 108 deletions
  1. 69 108
      examples/js/ShaderDeferred.js

+ 69 - 108
examples/js/ShaderDeferred.js

@@ -25,6 +25,30 @@ THREE.DeferredShaderChunk = {
 
 	].join("\n"),
 
+	computeVertexPositionVS: [
+
+		"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
+
+		"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
+		"float z = normalDepth.w;",
+
+		"if ( z == 0.0 ) discard;",
+
+		"vec2 xy = texCoord * 2.0 - 1.0;",
+
+		"vec4 vertexPositionProjected = vec4( xy, z, 1.0 );",
+		"vec4 vertexPositionVS = matProjInverse * vertexPositionProjected;",
+		"vertexPositionVS.xyz /= vertexPositionVS.w;",
+		"vertexPositionVS.w = 1.0;",
+
+	].join("\n"),
+
+	computeNormal: [
+
+		"vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
+
+	].join("\n"),
+
 	unpackColorMap: [
 
 		"vec4 colorMap = texture2D( samplerColor, texCoord );",
@@ -419,8 +443,6 @@ THREE.ShaderDeferred = {
 
 		fragmentShader : [
 
-			"varying vec4 clipPos;",
-
 			"uniform sampler2D samplerColor;",
 			"uniform sampler2D samplerNormalDepth;",
 
@@ -438,57 +460,31 @@ THREE.ShaderDeferred = {
 
 			"void main() {",
 
-				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-
-				"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
-
-				"float z = normalDepth.w;",
-				"float lightZ = clipPos.z / clipPos.w;",
-
-				//"if ( z == 0.0 || lightZ > z ) discard;",
-
-				"float x = texCoord.x * 2.0 - 1.0;",
-				"float y = texCoord.y * 2.0 - 1.0;",
-
-				"vec4 projectedPos = vec4( x, y, z, 1.0 );",
+				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
 
-				"vec4 viewPos = matProjInverse * projectedPos;",
-				"viewPos.xyz /= viewPos.w;",
-				"viewPos.w = 1.0;",
+				// bail out early when pixel outside of light sphere
 
-				"vec3 lightDir = lightPositionVS - viewPos.xyz;",
-				"float dist = length( lightDir );",
+				"vec3 lightDirection = lightPositionVS - vertexPositionVS.xyz;",
+				"float distance = length( lightDirection );",
 
-				"if ( dist > lightRadius ) discard;",
-
-				"lightDir = normalize( lightDir );",
-
-				"float cutoff = 0.3;",
-				"float denom = dist/lightRadius + 1.0;",
-				"float attenuation = 1.0 / ( denom * denom );",
-				"attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );",
-				"attenuation = max( attenuation, 0.0 );",
-				"attenuation *= attenuation;",
-
-				// normal
-
-				"vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
-
-				// color
+				"if ( distance > lightRadius ) discard;",
 
+				THREE.DeferredShaderChunk[ "computeNormal" ],
 				THREE.DeferredShaderChunk[ "unpackColorMap" ],
 
-				// light
+				// compute light
+
+				"lightDirection = normalize( lightDirection );",
 
 				"vec3 diffuse;",
 
-				"float diffuseFull = max( dot( normal, lightDir ), 0.0 );",
+				"float diffuseFull = max( dot( normal, lightDirection ), 0.0 );",
 
 				"if ( wrapAround < 0.0 ) {",
 
 					// wrap around lighting
 
-					"float diffuseHalf = max( 0.5 + 0.5 * dot( normal, lightDir ), 0.0 );",
+					"float diffuseHalf = max( 0.5 + 0.5 * dot( normal, lightDirection ), 0.0 );",
 
 					"const vec3 wrapRGB = vec3( 0.6, 0.2, 0.2 );",
 					"diffuse = mix( vec3( diffuseFull ), vec3( diffuseHalf ), wrapRGB );",
@@ -503,7 +499,7 @@ THREE.ShaderDeferred = {
 
 				// specular
 
-				"vec3 halfVector = normalize( lightDir - normalize( viewPos.xyz ) );",
+				"vec3 halfVector = normalize( lightDirection - normalize( vertexPositionVS.xyz ) );",
 				"float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
 
 				// simple specular
@@ -514,11 +510,18 @@ THREE.ShaderDeferred = {
 
 				"float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
 
-				"vec3 schlick = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightDir, halfVector ), 5.0 );",
+				"vec3 schlick = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightDirection, halfVector ), 5.0 );",
 				"vec3 specular = schlick * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse * specularNormalization;",
 
 				// combine
 
+				"float cutoff = 0.3;",
+				"float denom = distance / lightRadius + 1.0;",
+				"float attenuation = 1.0 / ( denom * denom );",
+				"attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );",
+				"attenuation = max( attenuation, 0.0 );",
+				"attenuation *= attenuation;",
+
 				THREE.DeferredShaderChunk[ "combine" ],
 
 			"}"
@@ -527,13 +530,12 @@ THREE.ShaderDeferred = {
 
 		vertexShader : [
 
-			"varying vec4 clipPos;",
-
 			"void main() { ",
 
+				// sphere proxy needs real position
+
 				"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
 				"gl_Position = projectionMatrix * mvPosition;",
-				"clipPos = gl_Position;",
 
 			"}"
 
@@ -581,32 +583,13 @@ THREE.ShaderDeferred = {
 
 			"void main() {",
 
-				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-
-				"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
-				"float z = normalDepth.w;",
-
-				"if ( z == 0.0 ) discard;",
-
-				"float x = texCoord.x * 2.0 - 1.0;",
-				"float y = texCoord.y * 2.0 - 1.0;",
-
-				"vec4 projectedPos = vec4( x, y, z, 1.0 );",
-				"vec4 positionVS = matProjInverse * projectedPos;",
-				"positionVS.xyz /= positionVS.w;",
-				"positionVS.w = 1.0;",
-
-				// normal
-
-				"vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
-
-				// color
-
+				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
+				THREE.DeferredShaderChunk[ "computeNormal" ],
 				THREE.DeferredShaderChunk[ "unpackColorMap" ],
 
-				//
+				// compute light
 
-				"vec3 surfToLight = normalize( lightPositionVS.xyz - positionVS.xyz );",
+				"vec3 surfToLight = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
 				"float dotProduct = max( dot( normal, surfToLight ), 0.0 );",
 
 				"float rho = dot( lightDirectionVS, surfToLight );",
@@ -636,7 +619,7 @@ THREE.ShaderDeferred = {
 
 					"float diffuse = spot * dotProduct;",
 
-					"vec3 halfVector = normalize( surfToLight - normalize( positionVS.xyz ) );",
+					"vec3 halfVector = normalize( surfToLight - normalize( vertexPositionVS.xyz ) );",
 					"float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
 
 					// simple specular
@@ -663,6 +646,8 @@ THREE.ShaderDeferred = {
 
 			"void main() { ",
 
+				// full screen quad proxy
+
 				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
 
 			"}"
@@ -706,56 +691,37 @@ THREE.ShaderDeferred = {
 
 			"void main() {",
 
-				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
-
-				"vec4 normalDepth = texture2D( samplerNormalDepth, texCoord );",
-				"float z = normalDepth.w;",
-
-				"if ( z == 0.0 ) discard;",
-
-				"float x = texCoord.x * 2.0 - 1.0;",
-				"float y = texCoord.y * 2.0 - 1.0;",
-
-				"vec4 projectedPos = vec4( x, y, z, 1.0 );",
-
-				"vec4 viewPos = matProjInverse * projectedPos;",
-				"viewPos.xyz /= viewPos.w;",
-				"viewPos.w = 1.0;",
-
-				// normal
-
-				"vec3 normal = normalDepth.xyz * 2.0 - 1.0;",
-
-				// color
-
+				THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
+				THREE.DeferredShaderChunk[ "computeNormal" ],
 				THREE.DeferredShaderChunk[ "unpackColorMap" ],
 
+				// compute light
+
 				"vec3 diffuse;",
 
 				"float dotProduct = dot( normal, lightDirectionVS );",
-
 				"float diffuseFull = max( dotProduct, 0.0 );",
 
-				// wrap around lighting
-
 				"if ( wrapAround < 0.0 ) {",
 
+					// wrap around lighting
+
 					"float diffuseHalf = max( 0.5 + 0.5 * dotProduct, 0.0 );",
 
 					"const vec3 wrapRGB = vec3( 0.2, 0.2, 0.2 );",
-					"diffuse = mix( vec3 ( diffuseFull ), vec3( diffuseHalf ), wrapRGB );",
-
-				// simple lighting
+					"diffuse = mix( vec3( diffuseFull ), vec3( diffuseHalf ), wrapRGB );",
 
 				"} else {",
 
-					"diffuse = vec3 ( diffuseFull );",
+					// simple lighting
+
+					"diffuse = vec3( diffuseFull );",
 
 				"}",
 
 				// specular
 
-				"vec3 halfVector = normalize( lightDirectionVS - normalize( viewPos.xyz ) );",
+				"vec3 halfVector = normalize( lightDirectionVS - normalize( vertexPositionVS.xyz ) );",
 				"float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
 
 				// simple specular
@@ -783,6 +749,8 @@ THREE.ShaderDeferred = {
 
 			"void main() { ",
 
+				// full screen quad proxy
+
 				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
 
 			"}"
@@ -808,16 +776,7 @@ THREE.ShaderDeferred = {
 			"uniform float viewHeight;",
 			"uniform float viewWidth;",
 
-			"vec3 float_to_vec3( float data ) {",
-
-				"vec3 uncompressed;",
-				"uncompressed.x = fract( data );",
-				"float zInt = floor( data / 255.0 );",
-				"uncompressed.z = fract( zInt / 255.0 );",
-				"uncompressed.y = fract( floor( data - ( zInt * 255.0 ) ) / 255.0 );",
-				"return uncompressed;",
-
-			"}",
+			THREE.DeferredShaderChunk[ "unpackFloat" ],
 
 			"void main() {",
 
@@ -836,6 +795,8 @@ THREE.ShaderDeferred = {
 
 			"void main() { ",
 
+				// full screen quad proxy
+
 				"gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
 
 			"}"