Browse Source

attempt to simplify the phong shaders and lights.

Ben Houston 9 years ago
parent
commit
ea9cfe0cfe

+ 37 - 36
src/renderers/shaders/ShaderChunk/common.glsl

@@ -1,5 +1,6 @@
 #define PI 3.14159
 #define PI 3.14159
 #define PI2 6.28318
 #define PI2 6.28318
+#define RECIPROCAL_PI 0.31830988618
 #define RECIPROCAL_PI2 0.15915494
 #define RECIPROCAL_PI2 0.15915494
 #define LOG2 1.442695
 #define LOG2 1.442695
 #define EPSILON 1e-6
 #define EPSILON 1e-6
@@ -52,6 +53,41 @@ float calcLightAttenuation( float lightDistance, float cutoffDistance, float dec
 
 
 }
 }
 
 
+vec3 inputToLinear( in vec3 a ) {
+
+	#ifdef GAMMA_INPUT
+
+		return pow( a, vec3( float( GAMMA_FACTOR ) ) );
+
+	#else
+
+		return a;
+
+	#endif
+
+}
+
+vec3 linearToOutput( in vec3 a ) {
+
+	#ifdef GAMMA_OUTPUT
+
+		return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );
+
+	#else
+
+		return a;
+
+	#endif
+
+}
+
+
+vec3 BRDF_Lambert( in vec3 diffuseColor, in float dotLN ) {
+
+	return diffuseColor * ( dotLN * RECIPROCAL_PI );
+
+}
+
 vec3 F_Schlick( in vec3 specularColor, in float dotLH ) {
 vec3 F_Schlick( in vec3 specularColor, in float dotLH ) {
 
 
 	// Original approximation by Christophe Schlick '94
 	// Original approximation by Christophe Schlick '94
@@ -80,49 +116,14 @@ float D_BlinnPhong( in float shininess, in float dotNH ) {
 
 
 }
 }
 
 
-vec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in vec3 normal, in vec3 lightDir, in vec3 viewDir ) {
-
-	vec3 halfDir = normalize( lightDir + viewDir );
-
-	//float dotNL = saturate( dot( normal, lightDir ) );
-	//float dotNV = saturate( dot( normal, viewDir ) );
-	float dotNH = saturate( dot( normal, halfDir ) );
-	float dotLH = saturate( dot( lightDir, halfDir ) );
+vec3 BRDF_BlinnPhong( in vec3 specularColor, in float shininess, in float dotNH, in float dotLH ) {
 
 
 	vec3 F = F_Schlick( specularColor, dotLH );
 	vec3 F = F_Schlick( specularColor, dotLH );
-
 	float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );
 	float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );
-
 	float D = D_BlinnPhong( shininess, dotNH );
 	float D = D_BlinnPhong( shininess, dotNH );
 
 
 	return F * G * D;
 	return F * G * D;
 
 
 }
 }
 
 
-vec3 inputToLinear( in vec3 a ) {
-
-	#ifdef GAMMA_INPUT
-
-		return pow( a, vec3( float( GAMMA_FACTOR ) ) );
-
-	#else
-
-		return a;
-
-	#endif
 
 
-}
-
-vec3 linearToOutput( in vec3 a ) {
-
-	#ifdef GAMMA_OUTPUT
-
-		return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );
-
-	#else
-
-		return a;
-
-	#endif
-
-}

+ 42 - 65
src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl

@@ -1,34 +1,33 @@
 vec3 viewDir = normalize( vViewPosition );
 vec3 viewDir = normalize( vViewPosition );
 
 
-vec3 totalDiffuseLight = vec3( 0.0 );
-vec3 totalSpecularLight = vec3( 0.0 );
+vec3 totalReflectedLight = vec3( 0.0 );
 
 
-#if MAX_POINT_LIGHTS > 0
-
-	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
-
-		vec3 lightColor = pointLightColor[ i ];
-
-		vec3 lightPosition = pointLightPosition[ i ];
-		vec3 lVector = lightPosition + vViewPosition.xyz;
-		vec3 lightDir = normalize( lVector );
+#ifdef METAL
 
 
-		// attenuation
+	diffuseColor.rgb = diffuseColor.rgb * specular;
 
 
-		float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );
+#endif
 
 
-		// diffuse
+#if MAX_POINT_LIGHTS > 0
 
 
-		float cosineTerm = saturate( dot( normal, lightDir ) );
+	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
 
 
-		totalDiffuseLight += lightColor * attenuation * cosineTerm;
+		vec3 lightDir, lightIntensity;
+		getSpotLight( i, lightDir, lightIntensity );
 
 
-		// specular
+		if( dot( lightIntensity, lightIntensity ) > 0.0 ) {
 
 
-		vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir );
+			vec3 halfDir = normalize( lightDir + viewDir );
+			float dotNL = saturate( dot( normal, lightDir ) );
+			float dotNH = saturate( dot( normal, halfDir ) );
+			float dotLH = saturate( dot( lightDir, halfDir ) );
 
 
-		totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;
+			totalReflectedLight += (
+				BRDF_Lambert( diffuseColor.rgb, dotNL ) +
+				BRDF_BlinnPhong( specular, shininess, dotNH, dotLH )
+				) * lightIntensity;
 
 
+		}
 
 
 	}
 	}
 
 
@@ -38,35 +37,20 @@ vec3 totalSpecularLight = vec3( 0.0 );
 
 
 	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {
 	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {
 
 
-		vec3 lightColor = spotLightColor[ i ];
-
-		vec3 lightPosition = spotLightPosition[ i ];
-		vec3 lVector = lightPosition + vViewPosition.xyz;
-		vec3 lightDir = normalize( lVector );
-
-		float spotEffect = dot( spotLightDirection[ i ], lightDir );
-
-		if ( spotEffect > spotLightAngleCos[ i ] ) {
-
-			spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ i ] ) );
-
-			// attenuation
+		vec3 lightDir, lightIntensity;
+		getSpotLight( i, lightDir, lightIntensity );
 
 
-			float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] );
+		if( dot( lightIntensity, lightIntensity ) > 0.0 ) {
 
 
-			attenuation *= spotEffect;
+			vec3 halfDir = normalize( lightDir + viewDir );
+			float dotNL = saturate( dot( normal, lightDir ) );
+			float dotNH = saturate( dot( normal, halfDir ) );
+			float dotLH = saturate( dot( lightDir, halfDir ) );
 
 
-			// diffuse
-
-			float cosineTerm = saturate( dot( normal, lightDir ) );
-
-			totalDiffuseLight += lightColor * attenuation * cosineTerm;
-
-			// specular
-
-			vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir );
-
-			totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;
+			totalReflectedLight += (
+				BRDF_Lambert( diffuseColor.rgb, dotNL ) +
+				BRDF_BlinnPhong( specular, shininess, dotNH, dotLH )
+				) * lightIntensity;
 
 
 		}
 		}
 
 
@@ -78,32 +62,25 @@ vec3 totalSpecularLight = vec3( 0.0 );
 
 
 	for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
 	for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {
 
 
-		vec3 lightColor = directionalLightColor[ i ];
-
-		vec3 lightDir = directionalLightDirection[ i ];
-
-		// diffuse
-
-		float cosineTerm = saturate( dot( normal, lightDir ) );
+		vec3 lightDir, lightIntensity;
+		getDirLight( i, lightDir, lightIntensity );
 
 
-		totalDiffuseLight += lightColor * cosineTerm;
+		if( dot( lightIntensity, lightIntensity ) > 0.0 ) {
 
 
-		// specular
+			vec3 halfDir = normalize( lightDir + viewDir );
+			float dotNL = saturate( dot( normal, lightDir ) );
+			float dotNH = saturate( dot( normal, halfDir ) );
+			float dotLH = saturate( dot( lightDir, halfDir ) );
 
 
-		vec3 brdf = BRDF_BlinnPhong( specular, shininess, normal, lightDir, viewDir );
+			totalReflectedLight += (
+				BRDF_Lambert( diffuseColor.rgb, dotNL ) +
+				BRDF_BlinnPhong( specular, shininess, dotNH, dotLH )
+				) * lightIntensity;
 
 
-		totalSpecularLight += brdf * specularStrength * lightColor * cosineTerm;
+		}
 
 
 	}
 	}
 
 
 #endif
 #endif
 
 
-#ifdef METAL
-
-	outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) * specular + totalSpecularLight + totalEmissiveLight;
-
-#else
-
-	outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + totalAmbientLight ) + totalSpecularLight + totalEmissiveLight;
-
-#endif
+outgoingLight += totalReflectedLight + totalEmissiveLight;

+ 48 - 10
src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl

@@ -1,10 +1,31 @@
 uniform vec3 ambientLightColor;
 uniform vec3 ambientLightColor;
 
 
+#if MAX_SPOT_LIGHTS > 0 || defined( USE_ENVMAP )
+
+	varying vec3 vWorldPosition;
+
+#endif
+
+varying vec3 vViewPosition;
+
+#ifndef FLAT_SHADED
+
+	varying vec3 vNormal;
+
+#endif
+
 #if MAX_DIR_LIGHTS > 0
 #if MAX_DIR_LIGHTS > 0
 
 
 	uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];
 	uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];
 	uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];
 	uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];
 
 
+	#define getDirLight( directionalIndex, lightDir, lightIntensity ) { 
+	
+		lightDir = directionalLightDirection[ directionalIndex ]; 
+		lightIntensity = directionalLightColor[ directionalIndex ]; 
+	
+	}
+
 #endif
 #endif
 
 
 #if MAX_HEMI_LIGHTS > 0
 #if MAX_HEMI_LIGHTS > 0
@@ -18,11 +39,22 @@ uniform vec3 ambientLightColor;
 #if MAX_POINT_LIGHTS > 0
 #if MAX_POINT_LIGHTS > 0
 
 
 	uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];
 	uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];
-
 	uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];
 	uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];
 	uniform float pointLightDistance[ MAX_POINT_LIGHTS ];
 	uniform float pointLightDistance[ MAX_POINT_LIGHTS ];
 	uniform float pointLightDecay[ MAX_POINT_LIGHTS ];
 	uniform float pointLightDecay[ MAX_POINT_LIGHTS ];
 
 
+	#define getPointLight( pointIndex, lightDir, lightIntensity ) { 
+	
+		vec3 lightPosition = pointLightPosition[ pointIndex ]; 
+	
+		vec3 lVector = lightPosition + vViewPosition.xyz; 
+		lightDir = normalize( lVector ); 
+	
+		lightIntensity = pointLightColor[ pointIndex ]; 
+		lightIntensity *= calcLightAttenuation( length( lVector ), pointLightDistance[ pointIndex ], pointLightDecay[ pointIndex ] ); 
+	
+	}
+
 #endif
 #endif
 
 
 #if MAX_SPOT_LIGHTS > 0
 #if MAX_SPOT_LIGHTS > 0
@@ -35,18 +67,24 @@ uniform vec3 ambientLightColor;
 	uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];
 	uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];
 	uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];
 	uniform float spotLightDecay[ MAX_SPOT_LIGHTS ];
 
 
-#endif
-
-#if MAX_SPOT_LIGHTS > 0 || defined( USE_ENVMAP )
-
-	varying vec3 vWorldPosition;
+	#define getSpotLight( spotIndex, lightDir, lightIntensity ) {
+	
+		vec3 lightPosition = spotLightPosition[ spotIndex ];
+	
+		vec3 lVector = lightPosition + vViewPosition.xyz;
+		lightDir = normalize( lVector );
+	
+		float spotEffect = dot( spotLightDirection[ spotIndex ], lightDir );
+		spotEffect = saturate( pow( saturate( spotEffect ), spotLightExponent[ spotIndex ] ) );
+	
+		lightIntensity = spotLightColor[ spotIndex ];
+		lightIntensity *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLightDistance[ spotIndex ], spotLightDecay[ spotIndex ] ) );
+
+	}
 
 
 #endif
 #endif
 
 
-varying vec3 vViewPosition;
 
 
-#ifndef FLAT_SHADED
 
 
-	varying vec3 vNormal;
 
 
-#endif
+