Skip to content

Commit f0a483f

Browse files
committed
shadowmap stabilization
1 parent 74e9ab4 commit f0a483f

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

data/cage/shaders/functions/sampleShadowMap.glsl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ $include randomAngle.glsl
44

55
float sampleShadowMap2d(sampler2DArray texShadow2d, vec3 shadowPos, int cascade)
66
{
7-
vec2 radius = 0.8 / textureSize(texShadow2d, 0).xy;
7+
// return float(texture(texShadow2d, vec3(shadowPos.xy, float(cascade))).x > shadowPos.z);
8+
9+
vec2 radius = 1.3 / textureSize(texShadow2d, 0).xy;
810
float visibility = 0.0;
911
for (int i = 0; i < 4; i++)
1012
{

sources/libengine/graphics/renderPipeline.cpp

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)