@@ -262,21 +262,29 @@ void renderShadowPassFromFrustum(CommandBuffer &cmdBuf, ShadowMapPass &passInfo,
262262 std::span<const DirectionalLight> dirLight,
263263 std::span<const OpaqueCastable> castables,
264264 const FrustumCornersType &worldSpaceCorners) {
265- using Eigen::Vector3d;
266-
267265 auto [center, radius] = frustumBoundingSphereCenterRadius (worldSpaceCorners);
268- radius = std::ceil (radius * 16 .f ) / 16 .f ;
269266
270267 for (size_t i = 0 ; i < passInfo.numLights (); i++) {
271- const Float3 eye = center - radius * dirLight[i].direction .normalized ();
268+ Float3 eye = center - radius * dirLight[i].direction .normalized ();
269+ Mat4f tmpLightView = lookAt (eye, center, Float3::UnitZ ());
270+ // transform corners to light-space
271+ FrustumCornersType corners = worldSpaceCorners;
272+ frustumApplyTransform (corners, tmpLightView);
273+
274+ coal::AABB bounds;
275+ for (const auto &c : corners) {
276+ bounds += c.cast <coal::CoalScalar>();
277+ }
278+ float r = float (bounds.max_ .z ());
279+
272280 auto &lightView = passInfo.cam [i].view ;
273281 auto &lightProj = passInfo.cam [i].projection ;
282+ eye = center - r * dirLight[i].direction .normalized ();
274283 lightView = lookAt (eye, center, Float3::UnitZ ());
275284
276- AABB bounds{Vector3d::Constant (-radius), Vector3d::Constant (radius)};
277285 lightProj = shadowOrthographicMatrix ({bounds.width (), bounds.height ()},
278- float (bounds.min_ .z ()),
279- float (bounds.max_ .z ()));
286+ float (bounds.max_ .z ()),
287+ float (bounds.min_ .z ()));
280288 }
281289 passInfo.render (cmdBuf, castables);
282290}
@@ -285,28 +293,21 @@ void renderShadowPassFromAABB(CommandBuffer &cmdBuf, ShadowMapPass &passInfo,
285293 std::span<const DirectionalLight> dirLight,
286294 std::span<const OpaqueCastable> castables,
287295 const AABB &worldAABB) {
288- using Eigen::Vector3d;
289-
290296 Float3 center = worldAABB.center ().cast <float >();
291297
292298 for (size_t i = 0 ; i < passInfo.numLights (); i++) {
293- Float3 tmpEye = center - 100 .0f * dirLight[i].direction .normalized ();
294- Mat4f tmplightView = lookAt (tmpEye, center, Float3::UnitZ ());
299+ Float3 eye = center - 100 .0f * dirLight[i].direction .normalized ();
300+ Mat4f tmpLightView = lookAt (eye, center, Float3::UnitZ ());
301+ AABB bounds = applyTransformToAABB (worldAABB, tmpLightView);
295302
296303 auto &lightView = passInfo.cam [i].view ;
297304 auto &lightProj = passInfo.cam [i].projection ;
298305
299- Mat3f R = tmplightView.topLeftCorner <3 , 3 >();
300- Float3 t = tmplightView.topRightCorner <3 , 1 >();
301- AABB bounds = coal::translate (coal::rotate (worldAABB, R.cast <double >()),
302- t.cast <double >());
303-
304- Float3 lightSpaceCenter = bounds.center ().cast <float >();
305306 float radius = float (bounds.max_ .z ());
306307
307- Float3 finalEye = center - radius * dirLight[i].direction .normalized ();
308+ eye = center - radius * dirLight[i].direction .normalized ();
308309
309- lightView = lookAt (finalEye , center, Float3::UnitZ ());
310+ lightView = lookAt (eye , center, Float3::UnitZ ());
310311 lightProj = shadowOrthographicMatrix ({bounds.width (), bounds.height ()},
311312 float (bounds.max_ .z ()),
312313 float (bounds.min_ .z ()));
0 commit comments