@@ -1488,29 +1488,67 @@ namespace cage
14881488					const  Vec4 a = invVP * Vec4 (p, 1 );
14891489					return  Vec3 (a) / a[3 ];
14901490				};
1491- 				Aabb worldBox;
1492- 				for  (Vec3 ndcP : { Vec3 (-1 , -1 , splitNearNdc), Vec3 (1 , -1 , splitNearNdc), Vec3 (1 , 1 , splitNearNdc), Vec3 (-1 , 1 , splitNearNdc), Vec3 (-1 , -1 , splitFarNdc), Vec3 (1 , -1 , splitFarNdc), Vec3 (1 , 1 , splitFarNdc), Vec3 (-1 , 1 , splitFarNdc) })
1493- 				{
1494- 					const  Vec3 wP = getPoint (ndcP);
1495- 					worldBox += Aabb (wP);
1496- 				}
1491+ 				//  world-space corners of the camera frustum slice
1492+ 				const  std::array<Vec3, 8 > corners = { getPoint (Vec3 (-1 , -1 , splitNearNdc)), getPoint (Vec3 (1 , -1 , splitNearNdc)), getPoint (Vec3 (1 , 1 , splitNearNdc)), getPoint (Vec3 (-1 , 1 , splitNearNdc)), getPoint (Vec3 (-1 , -1 , splitFarNdc)), getPoint (Vec3 (1 , -1 , splitFarNdc)), getPoint (Vec3 (1 , 1 , splitFarNdc)), getPoint (Vec3 (-1 , 1 , splitFarNdc)) };
14971493
14981494				const  Vec3 lightDir = Vec3 (model * Vec4 (0 , 0 , -1 , 0 ));
14991495				const  Vec3 lightUp = abs (dot (lightDir, Vec3 (0 , 1 , 0 ))) > 0.99  ? Vec3 (0 , 0 , 1 ) : Vec3 (0 , 1 , 0 );
1500- 				const  Vec3 eye = worldBox.center ();
1496+ 
1497+ #if  (0)
1498+ 
1499+ 				Sphere sph = makeSphere (corners);
1500+ 				view = Mat4 (inverse (Transform (sph.center , Quat (lightDir, lightUp))));
1501+ 
1502+ 				{ //  stabilization
1503+ 					const  Real texelSize = sph.radius  * 2  / sc.resolution ;
1504+ 					Vec3 snapOrigin = Vec3 (view * Vec4 (sph.center , 1 ));
1505+ 					snapOrigin /= texelSize;
1506+ 					for  (uint32 i = 0 ; i < 3 ; i++)
1507+ 						snapOrigin[i] = floor (snapOrigin[i]);
1508+ 					snapOrigin *= texelSize;
1509+ 					sph.center  = Vec3 (inverse (view) * Vec4 (snapOrigin, 1 ));
1510+ 					view = Mat4 (inverse (Transform (sph.center , Quat (lightDir, lightUp))));
1511+ 				}
1512+ 
1513+ 				Aabb shadowBox = Aabb (Sphere (Vec3 (), sph.radius ));
1514+ 
1515+ #else 
1516+ 
1517+ 				Aabb worldBox;
1518+ 				for  (Vec3 wp : corners)
1519+ 					worldBox += Aabb (wp);
1520+ 
1521+ 				Vec3 eye = worldBox.center ();
15011522				view = Mat4 (inverse (Transform (eye, Quat (lightDir, lightUp))));
15021523
15031524				Aabb shadowBox;
1504- 				for  (Vec3 corner : worldBox.corners ().data )
1505- 					shadowBox += Aabb (Vec3 (view * Vec4 (corner, 1 )));
1525+ 				for  (Vec3 wp : corners)
1526+ 					shadowBox += Aabb (Vec3 (view * Vec4 (wp, 1 )));
1527+ 
1528+ 				{ //  stabilization
1529+ 					const  Real texelSize = (shadowBox.b [0 ] - shadowBox.a [0 ]) / sc.resolution ;
1530+ 					Vec3 snapOrigin = Vec3 (view * Vec4 (worldBox.center (), 1 ));
1531+ 					snapOrigin /= texelSize;
1532+ 					for  (uint32 i = 0 ; i < 3 ; i++)
1533+ 						snapOrigin[i] = floor (snapOrigin[i]);
1534+ 					snapOrigin *= texelSize;
1535+ 					eye = Vec3 (inverse (view) * Vec4 (snapOrigin, 1 ));
1536+ 					view = Mat4 (inverse (Transform (eye, Quat (lightDir, lightUp))));
1537+ 
1538+ 					shadowBox = Aabb ();
1539+ 					for  (Vec3 wp : corners)
1540+ 						shadowBox += Aabb (Vec3 (view * Vec4 (wp, 1 )));
1541+ 				}
1542+ 
1543+ #endif 
15061544
15071545				//  adjust the shadow near and far planes to not exclude preceding shadow casters
15081546				shadowBox.a [2 ] -= sc.cascadesPaddingDistance ;
15091547				shadowBox.b [2 ] += sc.cascadesPaddingDistance ;
15101548
15111549				//  move far plane much further, to improve precision
15121550				const  Real currentDepth = -shadowBox.a [2 ] + shadowBox.b [2 ];
1513- 				shadowBox.a [2 ] -= currentDepth * 5 ;
1551+ 				shadowBox.a [2 ] -= currentDepth * 10 ;
15141552
15151553				projection = orthographicProjection (shadowBox.a [0 ], shadowBox.b [0 ], shadowBox.a [1 ], shadowBox.b [1 ], -shadowBox.b [2 ], -shadowBox.a [2 ]);
15161554
0 commit comments