forked from Mirrorlandia_minetest/minetest
Avoid shadow flicker at certain angles (#12961)
Change the way look direction and camera position are quantized when calculating light frustum
This commit is contained in:
parent
5f24a3c0c7
commit
70a82b0784
@ -41,10 +41,16 @@ static v3f quantizeDirection(v3f direction, float step)
|
|||||||
|
|
||||||
void DirectionalLight::createSplitMatrices(const Camera *cam)
|
void DirectionalLight::createSplitMatrices(const Camera *cam)
|
||||||
{
|
{
|
||||||
const float DISTANCE_STEP = BS * 2.0; // 2 meters
|
static const float COS_15_DEG = 0.965926f;
|
||||||
v3f newCenter;
|
v3f newCenter;
|
||||||
v3f look = cam->getDirection();
|
v3f look = cam->getDirection().normalize();
|
||||||
look = quantizeDirection(look, M_PI / 12.0); // 15 degrees
|
|
||||||
|
// if current look direction is < 15 degrees away from the captured
|
||||||
|
// look direction then stick to the captured value, otherwise recapture.
|
||||||
|
if (look.dotProduct(last_look) >= COS_15_DEG)
|
||||||
|
look = last_look;
|
||||||
|
else
|
||||||
|
last_look = look;
|
||||||
|
|
||||||
// camera view tangents
|
// camera view tangents
|
||||||
float tanFovY = tanf(cam->getFovY() * 0.5f);
|
float tanFovY = tanf(cam->getFovY() * 0.5f);
|
||||||
@ -56,10 +62,14 @@ void DirectionalLight::createSplitMatrices(const Camera *cam)
|
|||||||
|
|
||||||
// adjusted camera positions
|
// adjusted camera positions
|
||||||
v3f cam_pos_world = cam->getPosition();
|
v3f cam_pos_world = cam->getPosition();
|
||||||
cam_pos_world = v3f(
|
|
||||||
floor(cam_pos_world.X / DISTANCE_STEP) * DISTANCE_STEP,
|
// if world position is less than 1 block away from the captured
|
||||||
floor(cam_pos_world.Y / DISTANCE_STEP) * DISTANCE_STEP,
|
// world position then stick to the captured value, otherwise recapture.
|
||||||
floor(cam_pos_world.Z / DISTANCE_STEP) * DISTANCE_STEP);
|
if (cam_pos_world.getDistanceFromSQ(last_cam_pos_world) < BS * BS)
|
||||||
|
cam_pos_world = last_cam_pos_world;
|
||||||
|
else
|
||||||
|
last_cam_pos_world = cam_pos_world;
|
||||||
|
|
||||||
v3f cam_pos_scene = v3f(cam_pos_world.X - cam->getOffset().X * BS,
|
v3f cam_pos_scene = v3f(cam_pos_world.X - cam->getOffset().X * BS,
|
||||||
cam_pos_world.Y - cam->getOffset().Y * BS,
|
cam_pos_world.Y - cam->getOffset().Y * BS,
|
||||||
cam_pos_world.Z - cam->getOffset().Z * BS);
|
cam_pos_world.Z - cam->getOffset().Z * BS);
|
||||||
|
@ -114,6 +114,10 @@ private:
|
|||||||
|
|
||||||
v3f pos;
|
v3f pos;
|
||||||
v3f direction{0};
|
v3f direction{0};
|
||||||
|
|
||||||
|
v3f last_cam_pos_world{0,0,0};
|
||||||
|
v3f last_look{0,1,0};
|
||||||
|
|
||||||
shadowFrustum shadow_frustum;
|
shadowFrustum shadow_frustum;
|
||||||
shadowFrustum future_frustum;
|
shadowFrustum future_frustum;
|
||||||
bool dirty{false};
|
bool dirty{false};
|
||||||
|
Loading…
Reference in New Issue
Block a user