Przeglądaj źródła

Bugfix: Directional light tweaks
- Cascade frustum is now properly expanded to cover the extra fade region between the cascades
- Tweaked depth bias and soft transition region to reduce shadow acne and light leaking

BearishSun 7 lat temu
rodzic
commit
9ff5c6994f

BIN
Data/Engine/Shaders/ShadowProject.bsl.asset


+ 9 - 7
Source/RenderBeast/BsShadowRendering.cpp

@@ -1659,6 +1659,10 @@ namespace bs { namespace ct
 		float splitNear = getCSMSplitDistance(view, cascade, numCascades);
 		float splitNear = getCSMSplitDistance(view, cascade, numCascades);
 		float splitFar = getCSMSplitDistance(view, cascade + 1, numCascades);
 		float splitFar = getCSMSplitDistance(view, cascade + 1, numCascades);
 
 
+		// Increase by fade range, unless last cascade
+		if ((UINT32)(cascade + 1) < numCascades)
+				splitFar += CASCADE_FRACTION_FADE * (splitFar - splitNear);
+		
 		// Calculate the eight vertices of the split frustum
 		// Calculate the eight vertices of the split frustum
 		auto& viewProps = view.getProperties();
 		auto& viewProps = view.getProperties();
 
 
@@ -1850,6 +1854,9 @@ namespace bs { namespace ct
 		{
 		{
 		case LightType::Directional: 
 		case LightType::Directional: 
 			defaultBias = DIR_DEPTH_BIAS * deviceDepthRange;
 			defaultBias = DIR_DEPTH_BIAS * deviceDepthRange;
+
+			// Use larger bias for further away cascades
+			defaultBias *= depthRange * 0.01f;
 			break;
 			break;
 		case LightType::Radial: 
 		case LightType::Radial: 
 			defaultBias = RADIAL_LIGHT_BIAS;
 			defaultBias = RADIAL_LIGHT_BIAS;
@@ -1873,13 +1880,8 @@ namespace bs { namespace ct
 		// to account for radial light type.
 		// to account for radial light type.
 		if (light.getType() == LightType::Directional)
 		if (light.getType() == LightType::Directional)
 		{
 		{
-			// Reduce the size of the transition region when shadow map resolution is higher
-			float resolutionScale = 1.0f / (float)mapSize;
-
-			// Reduce the size of the transition region when the depth range is larger
-			float rangeScale = 1.0f / depthRange;
-
-			return DIR_LIGHT_SCALE * resolutionScale * rangeScale;
+			// Just use a large value, as we want a minimal transition region
+			return DIR_LIGHT_SCALE;
 		}
 		}
 		else
 		else
 			return fabs(light.getShadowBias()) * SPOT_LIGHT_SCALE;
 			return fabs(light.getShadowBias()) * SPOT_LIGHT_SCALE;