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
This commit is contained in:
Omar Emara
2025-06-04 12:24:33 +02:00
committed by Omar Emara
parent 889751b0c5
commit 6bf52d11f1
5 changed files with 23 additions and 11 deletions

View File

@@ -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,

View File

@@ -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. */

View File

@@ -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,