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.
This commit is contained in:
Omar Emara
2024-05-06 13:36:03 +03:00
parent db33ee0ba7
commit 7f222d0fe2
2 changed files with 12 additions and 8 deletions

View File

@@ -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);

View File

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