Fix #124339: Compositor artifacts with 0.5 translation

The compositor translate node produces artifacts when its fractional
part is 0.5. That's because GPUs do round-to-even for nearest neighbour
sampling in case samples were at pixel boundaries.

To fix this, we bias translations by a small value to break the
rounding and ensure predictable rounding direction.
This commit is contained in:
Bill Spitzak
2024-07-24 19:22:00 +03:00
committed by Omar Emara
parent 6041bdd93a
commit ab51d879c3
2 changed files with 11 additions and 2 deletions

View File

@@ -2,6 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include <limits>
#include "BLI_math_angle_types.hh"
#include "BLI_math_matrix.hh"
#include "BLI_math_matrix_types.hh"
@@ -85,7 +87,14 @@ void realize_on_domain(Context &context,
/* Invert the transformation because the shader transforms the domain coordinates instead of the
* input image itself and thus expect the inverse. */
const float3x3 inverse_transformation = math::invert(transformation);
float3x3 inverse_transformation = math::invert(transformation);
/* Bias translations in case of nearest interpolation to avoids the round-to-even behavior of
* some GPUs at pixel boundaries. */
if (realization_options.interpolation == Interpolation::Nearest) {
inverse_transformation = math::translate(
inverse_transformation, float2(-std::numeric_limits<float>::epsilon() * 10e3f));
}
GPU_shader_uniform_mat3_as_mat4(shader, "inverse_transformation", inverse_transformation.ptr());