diff --git a/irr/include/matrix4.h b/irr/include/matrix4.h index 020e2fde1..46d50292a 100644 --- a/irr/include/matrix4.h +++ b/irr/include/matrix4.h @@ -303,12 +303,14 @@ public: CMatrix4 &buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar, bool zClipFromZero = true); //! Builds a left-handed look-at matrix. + //! NOTE: upVector must not be collinear to the postion-to-target vector CMatrix4 &buildCameraLookAtMatrixLH( const vector3df &position, const vector3df &target, const vector3df &upVector); //! Builds a right-handed look-at matrix. + //! NOTE: upVector must not be collinear to the postion-to-target vector CMatrix4 &buildCameraLookAtMatrixRH( const vector3df &position, const vector3df &target, diff --git a/src/client/shadows/dynamicshadows.cpp b/src/client/shadows/dynamicshadows.cpp index 826e87d82..0f34f61fb 100644 --- a/src/client/shadows/dynamicshadows.cpp +++ b/src/client/shadows/dynamicshadows.cpp @@ -68,11 +68,17 @@ void DirectionalLight::createSplitMatrices(const Camera *cam) // we must compute the viewmat with the position - the camera offset // but the future_frustum position must be the actual world position v3f eye = center_scene - eye_displacement; + v3f up(0.0f, 1.0f, 0.0f); + // eye_displacement and up shall not be collinear + // At noon, light points straight down, the "up" vector can be anything + // that is not along the up axis + if (core::equals(eye_displacement.crossProduct(up).getLengthSQ(), 0.f)) + up = v3f(1.0f, 0.0f, 0.0f); future_frustum.player = cam_pos_scene; future_frustum.position = center_world - eye_displacement; future_frustum.length = length; future_frustum.radius = radius; - future_frustum.ViewMat.buildCameraLookAtMatrixLH(eye, center_scene, v3f(0.0f, 1.0f, 0.0f)); + future_frustum.ViewMat.buildCameraLookAtMatrixLH(eye, center_scene, up); future_frustum.ProjOrthMat.buildProjectionMatrixOrthoLH(radius, radius, 0.0f, length, false); }