From dfc58d282b62819e8b60e26bd1ff80102bf172ad Mon Sep 17 00:00:00 2001 From: Mark Stead Date: Tue, 15 Oct 2024 11:42:11 +0200 Subject: [PATCH] Fix #69731: Cycles: Vector Pass ignores animated FOV This PR fixes the motion vector values when using animation of the (perspective) camera focal length (and therefore changing the fov). Pull Request: https://projects.blender.org/blender/blender/pulls/127442 --- intern/cycles/scene/camera.cpp | 21 +++++++++++++-------- intern/cycles/scene/camera.h | 1 - 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/intern/cycles/scene/camera.cpp b/intern/cycles/scene/camera.cpp index cae46786cee..ae95c9ad278 100644 --- a/intern/cycles/scene/camera.cpp +++ b/intern/cycles/scene/camera.cpp @@ -275,7 +275,6 @@ void Camera::update(Scene *scene) rastertocamera = screentocamera * rastertoscreen; full_rastertocamera = screentocamera * full_rastertoscreen; - cameratoraster = screentoraster * cameratoscreen; cameratoworld = matrix; screentoworld = cameratoworld * screentocamera; @@ -354,7 +353,6 @@ void Camera::update(Scene *scene) } if (need_motion == Scene::MOTION_PASS) { - /* TODO(sergey): Support perspective (zoom, fov) motion. */ if (camera_type == CAMERA_PANORAMA) { if (have_motion) { kcam->motion_pass_pre = transform_inverse(motion[0]); @@ -366,9 +364,19 @@ void Camera::update(Scene *scene) } } else { - if (have_motion) { - kcam->perspective_pre = cameratoraster * transform_inverse(motion[0]); - kcam->perspective_post = cameratoraster * transform_inverse(motion[motion.size() - 1]); + if (have_motion || fov != fov_pre || fov != fov_post) { + /* Note the values for perspective_pre/perspective_post calculated for MOTION_PASS are + * different to those calculated for MOTION_BLUR below, so the code has not been combined. + */ + ProjectionTransform cameratoscreen_pre = projection_perspective( + fov_pre, nearclip, farclip); + ProjectionTransform cameratoscreen_post = projection_perspective( + fov_post, nearclip, farclip); + ProjectionTransform cameratoraster_pre = screentoraster * cameratoscreen_pre; + ProjectionTransform cameratoraster_post = screentoraster * cameratoscreen_post; + kcam->perspective_pre = cameratoraster_pre * transform_inverse(motion[0]); + kcam->perspective_post = cameratoraster_post * + transform_inverse(motion[motion.size() - 1]); } else { kcam->perspective_pre = worldtoraster; @@ -385,9 +393,6 @@ void Camera::update(Scene *scene) /* TODO(sergey): Support other types of camera. */ if (use_perspective_motion && camera_type == CAMERA_PERSPECTIVE) { - /* TODO(sergey): Move to an utility function and de-duplicate with - * calculation above. - */ ProjectionTransform screentocamera_pre = projection_inverse( projection_perspective(fov_pre, nearclip, farclip)); ProjectionTransform screentocamera_post = projection_inverse( diff --git a/intern/cycles/scene/camera.h b/intern/cycles/scene/camera.h index 358ff798f3a..6343ff9bd4a 100644 --- a/intern/cycles/scene/camera.h +++ b/intern/cycles/scene/camera.h @@ -159,7 +159,6 @@ class Camera : public Node { Transform worldtocamera; ProjectionTransform rastertocamera; - ProjectionTransform cameratoraster; ProjectionTransform full_rastertocamera;