aboutsummaryrefslogtreecommitdiff
path: root/src/client/shadows
diff options
context:
space:
mode:
authorx2048 <codeforsmile@gmail.com>2022-05-23 23:45:18 +0200
committerGitHub <noreply@github.com>2022-05-23 23:45:18 +0200
commited26ed5a1f49fc66facd4a745d29441aba5a92c3 (patch)
tree2cd07a00e55939c7ada57551049d962d2d063bf4 /src/client/shadows
parent16a30556dfa8e27c82d026bd63467f82d2e37a1c (diff)
downloadhax-minetest-server-ed26ed5a1f49fc66facd4a745d29441aba5a92c3.tar.gz
hax-minetest-server-ed26ed5a1f49fc66facd4a745d29441aba5a92c3.zip
Quantize light frustum calculations (#12357)
* Quantize light frustum calculations Reduces shadow flicker * Fix function name to match conventions
Diffstat (limited to 'src/client/shadows')
-rw-r--r--src/client/shadows/dynamicshadows.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/client/shadows/dynamicshadows.cpp b/src/client/shadows/dynamicshadows.cpp
index ca2d3ce37..9f26ba94a 100644
--- a/src/client/shadows/dynamicshadows.cpp
+++ b/src/client/shadows/dynamicshadows.cpp
@@ -27,10 +27,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
using m4f = core::matrix4;
+static v3f quantizeDirection(v3f direction, float step)
+{
+
+ float yaw = std::atan2(direction.Z, direction.X);
+ float pitch = std::asin(direction.Y); // assume look is normalized
+
+ yaw = std::floor(yaw / step) * step;
+ pitch = std::floor(pitch / step) * step;
+
+ return v3f(std::cos(yaw)*std::cos(pitch), std::sin(pitch), std::sin(yaw)*std::cos(pitch));
+}
+
void DirectionalLight::createSplitMatrices(const Camera *cam)
{
+ const float DISTANCE_STEP = BS * 2.0; // 2 meters
v3f newCenter;
v3f look = cam->getDirection();
+ look = quantizeDirection(look, M_PI / 12.0); // 15 degrees
// camera view tangents
float tanFovY = tanf(cam->getFovY() * 0.5f);
@@ -42,6 +56,10 @@ void DirectionalLight::createSplitMatrices(const Camera *cam)
// adjusted camera positions
v3f cam_pos_world = cam->getPosition();
+ cam_pos_world = v3f(
+ floor(cam_pos_world.X / DISTANCE_STEP) * DISTANCE_STEP,
+ floor(cam_pos_world.Y / DISTANCE_STEP) * DISTANCE_STEP,
+ floor(cam_pos_world.Z / DISTANCE_STEP) * DISTANCE_STEP);
v3f cam_pos_scene = v3f(cam_pos_world.X - cam->getOffset().X * BS,
cam_pos_world.Y - cam->getOffset().Y * BS,
cam_pos_world.Z - cam->getOffset().Z * BS);
@@ -61,7 +79,7 @@ void DirectionalLight::createSplitMatrices(const Camera *cam)
v3f boundVec = (cam_pos_scene + farCorner * sfFar) - center_scene;
float radius = boundVec.getLength();
float length = radius * 3.0f;
- v3f eye_displacement = direction * length;
+ v3f eye_displacement = quantizeDirection(direction, M_PI / 2880 /*15 seconds*/) * length;
// we must compute the viewmat with the position - the camera offset
// but the future_frustum position must be the actual world position