From 6bf52d11f1fbfc0726e17fc6ba9af2f7935f85ab Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Wed, 4 Jun 2025 12:24:33 +0200 Subject: [PATCH] Fix #139327: Movie distortion result is cropped The Movie distortion node crops its data if the movie size differs from the input size. That's because boundary extensions do not take calibration size into account. To fix this, we use the same coordinates range as the distortion grid computation, which computes the distortion in the space of the calibration size. Pull Request: https://projects.blender.org/blender/blender/pulls/139822 --- source/blender/blenkernel/BKE_tracking.h | 3 ++- source/blender/blenkernel/intern/tracking.cc | 20 ++++++++++++++----- .../intern/distortion_grid.cc | 3 ++- .../node_movie_distortion_distort.png | 4 ++-- .../node_movie_distortion_undistort.png | 4 ++-- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index eb0e8c3e78b..632d557e146 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -524,8 +524,9 @@ struct ImBuf *BKE_tracking_distort_frame(struct MovieTracking *tracking, * number of pixels that the image will grow/shrink by in each of the four bounds of the image as a * result of the distortion/undistortion. The deltas for the bounds are positive for expansion and * negative for shrinking. */ -void BKE_tracking_distortion_bounds_deltas(MovieTracking *tracking, +void BKE_tracking_distortion_bounds_deltas(MovieDistortion *distortion, const int size[2], + const int calibration_size[2], const bool undistort, int *r_right, int *r_left, diff --git a/source/blender/blenkernel/intern/tracking.cc b/source/blender/blenkernel/intern/tracking.cc index 675d10f41fc..0d665f6dce9 100644 --- a/source/blender/blenkernel/intern/tracking.cc +++ b/source/blender/blenkernel/intern/tracking.cc @@ -2530,8 +2530,9 @@ static Value parallel_reduce(const int range, reduction); } -void BKE_tracking_distortion_bounds_deltas(MovieTracking *tracking, +void BKE_tracking_distortion_bounds_deltas(MovieDistortion *distortion, const int size[2], + const int calibration_size[2], const bool undistort, int *r_right, int *r_left, @@ -2541,16 +2542,25 @@ void BKE_tracking_distortion_bounds_deltas(MovieTracking *tracking, using namespace blender; auto distortion_function = [&](const float2 &position) { - float2 distorted_position; + /* The tracking distortion functions expect the coordinates to be in the space of the image + * where the tracking camera was calibrated. So we first remap the coordinates into that space, + * apply the distortion, then remap back to the original coordinates space. This is done by + * dividing the by the size then multiplying by the calibration size, making sure to add 0.5 to + * evaluate at the center of pixels. */ + float2 coordinates = ((position + 0.5f) / float2(size)) * float2(calibration_size); /* Notice that the condition is inverted, that's because when we are undistorting, we compute * the boundaries by distorting and vice versa. */ + float2 distorted_coordinates; if (undistort) { - BKE_tracking_distort_v2(tracking, size[0], size[1], position, distorted_position); + BKE_tracking_distortion_distort_v2(distortion, coordinates, distorted_coordinates); } else { - BKE_tracking_undistort_v2(tracking, size[0], size[1], position, distorted_position); + BKE_tracking_distortion_undistort_v2(distortion, coordinates, distorted_coordinates); } - return distorted_position; + + /* We remap the coordinates back into the original size by dividing by the calibration size and + * multiplying by the size. */ + return (distorted_coordinates / float2(calibration_size)) * float2(size); }; /* Maximum distorted x location along the right edge of the image. */ diff --git a/source/blender/compositor/cached_resources/intern/distortion_grid.cc b/source/blender/compositor/cached_resources/intern/distortion_grid.cc index 3004dddb718..7f2a7635081 100644 --- a/source/blender/compositor/cached_resources/intern/distortion_grid.cc +++ b/source/blender/compositor/cached_resources/intern/distortion_grid.cc @@ -65,8 +65,9 @@ DistortionGrid::DistortionGrid( int left_delta; int bottom_delta; int top_delta; - BKE_tracking_distortion_bounds_deltas(&movie_clip->tracking, + BKE_tracking_distortion_bounds_deltas(distortion, size, + calibration_size, type == DistortionType::Undistort, &right_delta, &left_delta, diff --git a/tests/files/compositor/distort/compositor_renders/node_movie_distortion_distort.png b/tests/files/compositor/distort/compositor_renders/node_movie_distortion_distort.png index fb560546a90..e62ca8332df 100644 --- a/tests/files/compositor/distort/compositor_renders/node_movie_distortion_distort.png +++ b/tests/files/compositor/distort/compositor_renders/node_movie_distortion_distort.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3a29b30514f417d63baca391e1617d17634d82cb39b70b2686b89aa747aee767 -size 71864 +oid sha256:56aef728daf8e54bbb0eecede7d3315803ed26e0003d194c283c191810fcb4fb +size 71902 diff --git a/tests/files/compositor/distort/compositor_renders/node_movie_distortion_undistort.png b/tests/files/compositor/distort/compositor_renders/node_movie_distortion_undistort.png index 42791de60d0..ba923f4ef9c 100644 --- a/tests/files/compositor/distort/compositor_renders/node_movie_distortion_undistort.png +++ b/tests/files/compositor/distort/compositor_renders/node_movie_distortion_undistort.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:76cdb862082453b13c19b76a21ae15a37b67a75236359ffaa156b2ca26a77df1 -size 66890 +oid sha256:3f355f9e3cbc5975c6b0feea4c785629cabe43a89e6977c7b5dcb8ae856c78bc +size 63401