clementlandrin před 2 roky
rodič
revize
4be9724204
2 změnil soubory, kde provedl 28 přidání a 23 odebrání
  1. 23 20
      h3d/pass/CascadeShadowMap.hx
  2. 5 3
      h3d/shader/CascadeShadow.hx

+ 23 - 20
h3d/pass/CascadeShadowMap.hx

@@ -37,6 +37,18 @@ class CascadeShadowMap extends DirShadowMap {
 		return cshader.cascadeShadowMaps;
 		return cshader.cascadeShadowMaps;
 	}
 	}
 
 
+	function computeNearFar( i : Int ) {
+		var min = minDist < 0.0 ? ctx.camera.zNear : minDist;
+		var max = maxDist < 0.0 ? ctx.camera.zFar : maxDist;
+		if ( i == 0 ) {
+			return {near : min, far : min + firstCascadeSize};
+		}
+		var step = (max - min - firstCascadeSize) / (cascade - 1);
+		var near = min + firstCascadeSize + hxd.Math.pow((i - 1) / (cascade - 1), pow) * step;
+		var far = min + firstCascadeSize + hxd.Math.pow(i / (cascade - 1), pow) * step;
+		return {near : near, far : far};
+	}
+
 	public function updateCascadeBounds( camera : h3d.Camera ) {
 	public function updateCascadeBounds( camera : h3d.Camera ) {
 		var bounds = camera.orthoBounds;
 		var bounds = camera.orthoBounds;
 
 
@@ -48,9 +60,6 @@ class CascadeShadowMap extends DirShadowMap {
 			shadowNear = hxd.Math.min(shadowNear, corner.z / corner.w);
 			shadowNear = hxd.Math.min(shadowNear, corner.z / corner.w);
 			shadowFar = hxd.Math.max(shadowFar, corner.z / corner.w);
 			shadowFar = hxd.Math.max(shadowFar, corner.z / corner.w);
 		}
 		}
-		var step = (maxDist - minDist - firstCascadeSize) / (cascade - 1);
-		var near = minDist;
-		var far = minDist + firstCascadeSize;
 		for ( i in 0...cascade - 1 ) {
 		for ( i in 0...cascade - 1 ) {
 			var cascadeBounds = new h3d.col.Bounds();
 			var cascadeBounds = new h3d.col.Bounds();
 			function addCorner(x,y,d) {
 			function addCorner(x,y,d) {
@@ -65,15 +74,13 @@ class CascadeShadowMap extends DirShadowMap {
 				addCorner(1,1,d);
 				addCorner(1,1,d);
 			}
 			}
 
 
-			addCorners(near);
-			addCorners(far);
+			var nearFar = computeNearFar(i);
+			addCorners(nearFar.near);
+			addCorners(nearFar.far);
 			// Increasing z range has no effect on resolution, only on depth precision.
 			// Increasing z range has no effect on resolution, only on depth precision.
-			// cascadeBounds.zMax = lightCamera.orthoBounds.zMax;
-			// cascadeBounds.zMin = lightCamera.orthoBounds.zMin;
+			cascadeBounds.zMax = lightCamera.orthoBounds.zMax;
+			cascadeBounds.zMin = lightCamera.orthoBounds.zMin;
 			lightCameras[i].orthoBounds = cascadeBounds;
 			lightCameras[i].orthoBounds = cascadeBounds;
-
-			near = minDist + firstCascadeSize + hxd.Math.pow((i) / (cascade - 1), pow) * step;
-			far = minDist + firstCascadeSize + hxd.Math.pow((i+1) / (cascade - 1), pow) * step;
 		}
 		}
 		lightCameras[cascade - 1].orthoBounds = lightCamera.orthoBounds.clone();
 		lightCameras[cascade - 1].orthoBounds = lightCamera.orthoBounds.clone();
 	}
 	}
@@ -90,19 +97,15 @@ class CascadeShadowMap extends DirShadowMap {
 	function syncCascadeShader(textures : Array<h3d.mat.Texture>) {
 	function syncCascadeShader(textures : Array<h3d.mat.Texture>) {
 		cshader.DEBUG = debugShader;
 		cshader.DEBUG = debugShader;
 		for ( i in 0...cascade ) {
 		for ( i in 0...cascade ) {
-			cshader.cascadeShadowMaps[cascade - 1 - i] = textures[i];
-			cshader.cascadeProjs[cascade - 1 - i] = lightCameras[i].m;
+			var c = cascade - 1 - i;
+			cshader.cascadeShadowMaps[c] = textures[i];
+			cshader.cascadeProjs[c] = lightCameras[i].m;
 			if ( debugShader )
 			if ( debugShader )
-				cshader.cascadeDebugs[cascade - 1 - i] = h3d.Vector.fromColor(debugColors[i]);
-		}
-		for ( i in 0...cascade-1 ) {
-			var pt = lightCameras[i].unproject(0,0,1);
-			pt.transform(ctx.camera.m);
+				cshader.cascadeDebugs[c] = h3d.Vector.fromColor(debugColors[i]);
+			cshader.cascadeBias[c] = Math.pow(computeNearFar(i).far / computeNearFar(0).far, 1.2) * bias;
 		}
 		}
-		var pt = lightCamera.unproject(0,0,1);
-		pt.transform(ctx.camera.m);
 		cshader.CASCADE_COUNT = cascade;
 		cshader.CASCADE_COUNT = cascade;
-		cshader.shadowBias = bias / lightCamera.orthoBounds.zSize;
+		cshader.shadowBias = bias;
 		cshader.shadowPower = power;
 		cshader.shadowPower = power;
 		cshader.shadowProj = getShadowProj();
 		cshader.shadowProj = getShadowProj();
 
 

+ 5 - 3
h3d/shader/CascadeShadow.hx

@@ -11,6 +11,7 @@ class CascadeShadow extends DirShadow {
 		@param var cascadeShadowMaps : Array<Sampler2D, CASCADE_COUNT>;
 		@param var cascadeShadowMaps : Array<Sampler2D, CASCADE_COUNT>;
 		@param var cascadeProjs : Array<Mat3x4, CASCADE_COUNT>;
 		@param var cascadeProjs : Array<Mat3x4, CASCADE_COUNT>;
 		@param var cascadeDebugs : Array<Vec4, CASCADE_COUNT>;
 		@param var cascadeDebugs : Array<Vec4, CASCADE_COUNT>;
+		@param var cascadeBias : Array<Float, CASCADE_COUNT>;
 
 
 		function inside(pos : Vec3) : Bool {
 		function inside(pos : Vec3) : Bool {
 			if ( abs(pos.x) < 1.0 && abs(pos.y) < 1.0 && abs(pos.z) < 1.0 ) {
 			if ( abs(pos.x) < 1.0 && abs(pos.y) < 1.0 && abs(pos.z) < 1.0 ) {
@@ -31,6 +32,7 @@ class CascadeShadow extends DirShadow {
 						shadow = 1.0;
 						shadow = 1.0;
 						var zMax = shadowPos.z.saturate();
 						var zMax = shadowPos.z.saturate();
 						var shadowUv = screenToUv(shadowPos.xy);
 						var shadowUv = screenToUv(shadowPos.xy);
+						var bias = cascadeBias[c];
 						if( USE_PCF ) {
 						if( USE_PCF ) {
 							var rot = rand(transformedPosition.x + transformedPosition.y + transformedPosition.z) * 3.14 * 2;
 							var rot = rand(transformedPosition.x + transformedPosition.y + transformedPosition.z) * 3.14 * 2;
 							var cosR = cos(rot);
 							var cosR = cos(rot);
@@ -41,17 +43,17 @@ class CascadeShadow extends DirShadow {
 								var offset = poissonDisk[i].xy * offScale;
 								var offset = poissonDisk[i].xy * offScale;
 								offset = vec2(cosR * offset.x - sinR * offset.y, cosR * offset.y + sinR * offset.x);
 								offset = vec2(cosR * offset.x - sinR * offset.y, cosR * offset.y + sinR * offset.x);
 								var depth = cascadeShadowMaps[c].getLod(shadowUv + offset, 0).r;
 								var depth = cascadeShadowMaps[c].getLod(shadowUv + offset, 0).r;
-								shadow  -= (zMax - shadowBias > depth) ? sampleStrength : 0.0;
+								shadow  -= (zMax - bias > depth) ? sampleStrength : 0.0;
 							}
 							}
 						}
 						}
 						else if( USE_ESM ) {
 						else if( USE_ESM ) {
 							var depth = cascadeShadowMaps[c].get(shadowUv).r;
 							var depth = cascadeShadowMaps[c].get(shadowUv).r;
-							var delta = (depth + shadowBias).min(zMax) - zMax;
+							var delta = (depth + bias).min(zMax) - zMax;
 							shadow = exp(shadowPower * delta).saturate();		
 							shadow = exp(shadowPower * delta).saturate();		
 						}
 						}
 						else {
 						else {
 							var depth = cascadeShadowMaps[c].get(shadowUv).r;
 							var depth = cascadeShadowMaps[c].get(shadowUv).r;
-							shadow -= zMax - shadowBias > depth ? 1 : 0;
+							shadow -= zMax - bias > depth ? 1 : 0;
 						}
 						}
 					}
 					}
 				}
 				}