Kaynağa Gözat

Directional area light functional

BearishSun 8 yıl önce
ebeveyn
işleme
6f4c8d3a17

+ 6 - 8
Data/Raw/Engine/Includes/LightingCommon.bslinc

@@ -206,7 +206,7 @@ Technique
 				float roughness2 = max(surfaceData.roughness, 0.08f);
 				float roughness2 = max(surfaceData.roughness, 0.08f);
 				roughness2 *= roughness2;
 				roughness2 *= roughness2;
 				
 				
-				float3 lightContribution = 0;
+				float3 outLuminance = 0;
 				float alpha = 0.0f;
 				float alpha = 0.0f;
 				if(surfaceData.worldNormal.w > 0.0f)
 				if(surfaceData.worldNormal.w > 0.0f)
 				{
 				{
@@ -233,11 +233,9 @@ Technique
 							L = DoR < distanceToDisk ? normalize(distanceToDisk * L + S * diskRadius) : R;
 							L = DoR < distanceToDisk ? normalize(distanceToDisk * L + S * diskRadius) : R;
 						}
 						}
 						
 						
-						// TODO - Energy conservation term?
-
 						float3 surfaceShading = getSurfaceShading(V, L, specEnergy, surfaceData);
 						float3 surfaceShading = getSurfaceShading(V, L, specEnergy, surfaceData);
 						float illuminance = lightData.luminance * NoL;
 						float illuminance = lightData.luminance * NoL;
-						lightContribution += lightData.color * illuminance * surfaceShading;
+						outLuminance += lightData.color * illuminance * surfaceShading;
 					}
 					}
 					
 					
 					// Handle radial lights
 					// Handle radial lights
@@ -294,7 +292,7 @@ Technique
 						float attenuation = getRadialAttenuation(distToLightSqrd, lightData);
 						float attenuation = getRadialAttenuation(distToLightSqrd, lightData);
 						float3 surfaceShading = getSurfaceShading(V, L, specEnergy, surfaceData);
 						float3 surfaceShading = getSurfaceShading(V, L, specEnergy, surfaceData);
 							
 							
-						lightContribution += lightData.color * illuminance * attenuation * surfaceShading;
+						outLuminance += lightData.color * illuminance * attenuation * surfaceShading;
                     }
                     }
 
 
 					// Handle spot lights
 					// Handle spot lights
@@ -362,15 +360,15 @@ Technique
 						float attenuation = spotAttenuation * radialAttenuation;
 						float attenuation = spotAttenuation * radialAttenuation;
 						float3 surfaceShading = getSurfaceShading(V, L, specEnergy, surfaceData);
 						float3 surfaceShading = getSurfaceShading(V, L, specEnergy, surfaceData);
 							
 							
-						lightContribution += lightData.color * illuminance * attenuation * surfaceShading;
+						outLuminance += lightData.color * illuminance * attenuation * surfaceShading;
                     }
                     }
 					
 					
 					// Ambient term for in-editor visualization, not used in actual lighting
 					// Ambient term for in-editor visualization, not used in actual lighting
-					lightContribution += surfaceData.albedo.rgb * gAmbientFactor / PI;
+					outLuminance += surfaceData.albedo.rgb * gAmbientFactor / PI;
 					alpha = 1.0f;
 					alpha = 1.0f;
 				}
 				}
 				
 				
-				return float4(lightContribution, alpha);
+				return float4(outLuminance, alpha);
 			}
 			}
 		};
 		};
 	};
 	};

+ 5 - 5
Source/BansheeCore/Include/BsLight.h

@@ -96,12 +96,12 @@ namespace bs
 		 * Radius of the light source. If non-zero then this light represents an area light, otherwise it is a punctual
 		 * Radius of the light source. If non-zero then this light represents an area light, otherwise it is a punctual
 		 * light. Area lights have different attenuation then punctual lights, and their appearance in specular reflections
 		 * light. Area lights have different attenuation then punctual lights, and their appearance in specular reflections
 		 * is realistic. Shape of the area light depends on light type:
 		 * is realistic. Shape of the area light depends on light type:
-		 *  - For directional light the shape is a disc projected on the hemisphere on the horizon. This parameter
+		 *  - For directional light the shape is a disc projected on the hemisphere on the sky. This parameter
 		 *    represents angular radius (in degrees) of the disk and should be very small (think of how much space the Sun
 		 *    represents angular radius (in degrees) of the disk and should be very small (think of how much space the Sun
-		 *    takes on the sky - roughly 0.5 degrees).
-		 *  - For radial light the shape is a sphere and the radius is the radius of the sphere.
-		 *  - For spot lights the shape is a disc oriented in the direction of the spot light and the radius is the radius
-		 *    of the disc.
+		 *    takes on the sky - roughly 0.25 degree radius).
+		 *  - For radial light the shape is a sphere and the source radius is the radius of the sphere.
+		 *  - For spot lights the shape is a disc oriented in the direction of the spot light and the source radius is the
+		 *    radius of the disc.
 		 */
 		 */
 		void setSourceRadius(float radius);
 		void setSourceRadius(float radius);
 
 

+ 1 - 3
Source/BansheeCore/Source/BsLight.cpp

@@ -95,10 +95,8 @@ namespace bs
 		case LightType::Directional:
 		case LightType::Directional:
 			if (mSourceRadius > 0.0f)
 			if (mSourceRadius > 0.0f)
 			{
 			{
-				float angularDiameter = mSourceRadius * 2; // Assumed in degrees
-
 				// Use cone solid angle formulae to calculate disc solid angle
 				// Use cone solid angle formulae to calculate disc solid angle
-				float solidAngle = Math::TWO_PI * (1 - cos(0.5f * angularDiameter * Math::DEG2RAD));
+				float solidAngle = Math::TWO_PI * (1 - cos(mSourceRadius * Math::DEG2RAD));
 				return mIntensity / solidAngle; // Illuminance -> luminance
 				return mIntensity / solidAngle; // Illuminance -> luminance
 			}
 			}
 			else
 			else

+ 4 - 0
Source/RenderBeast/Source/BsLightRendering.cpp

@@ -39,6 +39,10 @@ namespace bs { namespace ct
 		output.attRadiusSqrdInv = 1.0f / (output.attRadius * output.attRadius);
 		output.attRadiusSqrdInv = 1.0f / (output.attRadius * output.attRadius);
 		output.color = Vector3(color.r, color.g, color.b);
 		output.color = Vector3(color.r, color.g, color.b);
 
 
+		// If directional lights, convert angular radius in degrees to radians
+		if (mInternal->getType() == LightType::Directional)
+			output.srcRadius *= Math::DEG2RAD;
+
 		// Create position for fake attenuation for area spot lights (with disc center)
 		// Create position for fake attenuation for area spot lights (with disc center)
 		if (mInternal->getType() == LightType::Spot)
 		if (mInternal->getType() == LightType::Spot)
 			output.shiftedLightPosition = output.position - output.direction * (output.srcRadius / Math::tan(spotAngle * 0.5f));
 			output.shiftedLightPosition = output.position - output.direction * (output.srcRadius / Math::tan(spotAngle * 0.5f));