From 7f222d0fe29f2ad48abb8b8902b7397ade9e421d Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Mon, 6 May 2024 13:36:03 +0300 Subject: [PATCH] Fix #121305: Corner Pin node returns single color The Corner Pin node as well as the Plane Track Deform nodes always return a single color that appears to be the average of the input. That's because the derivatives were computed in the sampler's space, while they should be in texel space. Large derivatives meant that the textureGrad function would always sample the lowest MIP level, hence the constant average color. This might be an issue with other uses of textureGrad in the compositor, so their use should be investigated. --- .../shaders/compositor_plane_deform.glsl | 10 ++++++---- .../shaders/compositor_plane_deform_motion_blur.glsl | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_plane_deform.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_plane_deform.glsl index ced3b24691f..9444ee154de 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_plane_deform.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_plane_deform.glsl @@ -7,17 +7,19 @@ void main() { ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + vec2 input_size = vec2(texture_size(input_tx)); - vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx)); + vec2 coordinates = (vec2(texel) + vec2(0.5)) / input_size; vec3 transformed_coordinates = mat3(homography_matrix) * vec3(coordinates, 1.0); vec2 projected_coordinates = transformed_coordinates.xy / transformed_coordinates.z; /* The derivatives of the projected coordinates with respect to x and y are the first and * second columns respectively, divided by the z projection factor as can be shown by - * differentiating the above matrix multiplication with respect to x and y. */ - vec2 x_gradient = homography_matrix[0].xy / transformed_coordinates.z; - vec2 y_gradient = homography_matrix[1].xy / transformed_coordinates.z; + * differentiating the above matrix multiplication with respect to x and y. Divide by the input + * size since textureGrad assumes derivatives with respect to texel coordinates. */ + vec2 x_gradient = (homography_matrix[0].xy / transformed_coordinates.z) / input_size.x; + vec2 y_gradient = (homography_matrix[1].xy / transformed_coordinates.z) / input_size.y; vec4 sampled_color = textureGrad(input_tx, projected_coordinates, x_gradient, y_gradient); diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_plane_deform_motion_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_plane_deform_motion_blur.glsl index e4981d6dacd..6ad6084225c 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_plane_deform_motion_blur.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_plane_deform_motion_blur.glsl @@ -7,8 +7,9 @@ void main() { ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + vec2 input_size = vec2(texture_size(input_tx)); - vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(imageSize(output_img)); + vec2 coordinates = (vec2(texel) + vec2(0.5)) / input_size; vec4 accumulated_color = vec4(0.0); for (int i = 0; i < number_of_motion_blur_samples; i++) { @@ -19,9 +20,10 @@ void main() /* The derivatives of the projected coordinates with respect to x and y are the first and * second columns respectively, divided by the z projection factor as can be shown by - * differentiating the above matrix multiplication with respect to x and y. */ - vec2 x_gradient = homography_matrix[0].xy / transformed_coordinates.z; - vec2 y_gradient = homography_matrix[1].xy / transformed_coordinates.z; + * differentiating the above matrix multiplication with respect to x and y. Divide by the input + * size since textureGrad assumes derivatives with respect to texel coordinates. */ + vec2 x_gradient = (homography_matrix[0].xy / transformed_coordinates.z) / input_size.x; + vec2 y_gradient = (homography_matrix[1].xy / transformed_coordinates.z) / input_size.y; vec4 sampled_color = textureGrad(input_tx, projected_coordinates, x_gradient, y_gradient); accumulated_color += sampled_color;