Browse Source

initial AreaLight implementation.

Ben Houston 9 years ago
parent
commit
36c599679b
1 changed files with 56 additions and 16 deletions
  1. 56 16
      src/renderers/shaders/ShaderChunk/common.glsl

+ 56 - 16
src/renderers/shaders/ShaderChunk/common.glsl

@@ -4,18 +4,15 @@
 #define RECIPROCAL_PI2 0.15915494
 #define LOG2 1.442695
 #define EPSILON 1e-6
-#define PHYSICALLY_BASED_RENDERING
 #define saturate(a) clamp( a, 0.0, 1.0 )
 #define whiteCompliment(a) ( 1.0 - saturate( a ) )
 
 float luminance( const in vec3 color ) {
-    const vec3 W = vec3(0.2125, 0.7154, 0.0721);
-    return dot( color, W );
+    return dot( color, vec3(0.2125, 0.7154, 0.0721) );
 }
 
 float average( const in vec3 color ) {
-    const vec3 W = vec3(0.3333, 0.3333, 0.3333);
-    return dot( color, W );
+    return dot( color, vec3(0.3333, 0.3333, 0.3333) );
 }
 
 vec3 transformDirection( in vec3 normal, in mat4 matrix ) {
@@ -170,10 +167,10 @@ float D_BlinnPhong( const in float shininess, const in float dotNH ) {
 
 }
 
-void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometryContext, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) {
+void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess, inout ReflectedLight reflectedLight ) {
 
-	vec3 halfDir = normalize( incidentLight.direction + geometryContext.viewDir );
-	float dotNH = saturate( dot( geometryContext.normal, halfDir ) );
+	vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );
+	float dotNH = saturate( dot( geometry.normal, halfDir ) );
 	float dotLH = saturate( dot( incidentLight.direction, halfDir ) );
 
 	vec3 F = F_Schlick( specularColor, dotLH );
@@ -193,7 +190,7 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo
 
 	uniform DirectionalLight directionalLights[ MAX_DIR_LIGHTS ];
 
-	void getDirIncidentLight( const in DirectionalLight directionalLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { 
+	void getDirIncidentLight( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { 
 	
 		incidentLight.color = directionalLight.color;
 		incidentLight.direction = directionalLight.direction; 
@@ -213,11 +210,11 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo
 
 	uniform PointLight pointLights[ MAX_POINT_LIGHTS ];
 
-	void getPointIncidentLight( const in PointLight pointLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { 
+	void getPointIncidentLight( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { 
 	
 		vec3 lightPosition = pointLight.position; 
 	
-		vec3 lVector = lightPosition - geometryContext.position; 
+		vec3 lVector = lightPosition - geometry.position; 
 		incidentLight.direction = normalize( lVector ); 
 	
 		incidentLight.color = pointLight.color; 
@@ -241,11 +238,11 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo
 
 	uniform SpotLight spotLights[ MAX_SPOT_LIGHTS ];
 
-	void getSpotIncidentLight( const in SpotLight spotLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) {
+	void getSpotIncidentLight( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight incidentLight ) {
 	
 		vec3 lightPosition = spotLight.position;
 	
-		vec3 lVector = lightPosition - geometryContext.position;
+		vec3 lVector = lightPosition - geometry.position;
 		incidentLight.direction = normalize( lVector );
 	
 		float spotEffect = dot( spotLight.direction, incidentLight.direction );
@@ -258,6 +255,49 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo
 
 #endif
 
+#define MAX_AREA_LIGHTS 0 
+
+#if MAX_AREA_LIGHTS > 0
+
+	struct HemisphereLight {
+	  vec3 position;
+	  vec3 width;
+	  vec3 height;
+	  vec3 color;
+	  float distance;
+	  float decay;
+	};
+
+	uniform AreaLight areaLights[ MAX_AREA_LIGHTS ];
+
+	void getAreaIncidentLight( const in AreaLight areaLight, const in GeometricContext geometry, out IncidentLight incidentLight ) {
+	
+		float widthLength = length( areaLight.width );
+		float heightLength = length( areaLight.height );
+
+		vec3 widthDir = areaLight.width / widthLength;
+		vec3 heightDir = areaLight.height / heightLength;
+		vec3 direction = normalize( cross( widthDir, heightDir ) );
+
+		// project onto plane and calculate direction from center to the projection.
+		vec3 planePosition = projectOnPlane( viewDir, areaLight.position, direction ),  // projection in plane
+		vec3 planeOffset = planePosition - areaLight.position;
+
+		// calculate distance from area:
+		vec2 planeOffsetUV = vec2( dot( planeOffset, widthDir ), dot( planeOffset, heightDir ) );
+		vec2 clampedPlaneOffsetUV = vec2( clamp( planeOffsetUV.x, -widthLength, widthLength ), clamp( planeOffsetUV.y, -heightLength, heightLength ) );
+		vec3 clampedPlanePosition = areaLight.position + ( widthDir * clampedPlaneOffsetUV.x + heightDir * clampedPlaneOffsetUV.y );
+
+		vec3 lVector = ( clampedPlanePosition - geometry.position );
+		float lLength = length( lVector );
+
+		incidentLight.color = areaLight.color[ i ] * calcLightAttenuation( lLength, areaLight.distance, areaLight.decay ) * 0.01;
+		incidentLight.direction = lVector / lLength;		
+
+	}
+
+#endif
+
 
 #if MAX_HEMI_LIGHTS > 0
 
@@ -269,15 +309,15 @@ void BRDF_BlinnPhong( const in IncidentLight incidentLight, const in GeometricCo
 
 	uniform HemisphereLight hemisphereLights[ MAX_HEMI_LIGHTS ];
 
-	void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in GeometricContext geometryContext, out IncidentLight incidentLight ) { 
+	void getHemisphereIncidentLight( const in HemisphereLight hemiLight, const in GeometricContext geometry, out IncidentLight incidentLight ) { 
 	
-		float dotNL = dot( geometryContext.normal, hemiLight.direction );
+		float dotNL = dot( geometry.normal, hemiLight.direction );
 
 		float hemiDiffuseWeight = 0.5 * dotNL + 0.5;
 
 		incidentLight.color = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );
 
-		incidentLight.direction = geometryContext.normal;
+		incidentLight.direction = geometry.normal;
 
 	}