mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16:13:46 +01:00
Quantize light frustum calculations (#12357)
* Quantize light frustum calculations Reduces shadow flicker * Fix function name to match conventions
This commit is contained in:
parent
16a30556df
commit
ed26ed5a1f
@ -27,10 +27,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
using m4f = core::matrix4;
|
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)
|
void DirectionalLight::createSplitMatrices(const Camera *cam)
|
||||||
{
|
{
|
||||||
|
const float DISTANCE_STEP = BS * 2.0; // 2 meters
|
||||||
v3f newCenter;
|
v3f newCenter;
|
||||||
v3f look = cam->getDirection();
|
v3f look = cam->getDirection();
|
||||||
|
look = quantizeDirection(look, M_PI / 12.0); // 15 degrees
|
||||||
|
|
||||||
// camera view tangents
|
// camera view tangents
|
||||||
float tanFovY = tanf(cam->getFovY() * 0.5f);
|
float tanFovY = tanf(cam->getFovY() * 0.5f);
|
||||||
@ -42,6 +56,10 @@ 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,
|
||||||
|
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,
|
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);
|
||||||
@ -61,7 +79,7 @@ void DirectionalLight::createSplitMatrices(const Camera *cam)
|
|||||||
v3f boundVec = (cam_pos_scene + farCorner * sfFar) - center_scene;
|
v3f boundVec = (cam_pos_scene + farCorner * sfFar) - center_scene;
|
||||||
float radius = boundVec.getLength();
|
float radius = boundVec.getLength();
|
||||||
float length = radius * 3.0f;
|
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
|
// we must compute the viewmat with the position - the camera offset
|
||||||
// but the future_frustum position must be the actual world position
|
// but the future_frustum position must be the actual world position
|
||||||
|
Loading…
Reference in New Issue
Block a user