Fix #124133: Compositor transforms are off by 0.5 pixels
The GPU compositor transforms are off by half a pixel in some cases. That's because the realization shader was to perform transforms, and it includes logic to move images by half a pixel if the domain and image had different even/odd sizes. To fix this, we only move by half a pixel if we are doing realization, while transforms are left as is.
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_math_matrix.hh"
|
||||
|
||||
#include "COM_algorithm_realize_on_domain.hh"
|
||||
#include "COM_context.hh"
|
||||
#include "COM_domain.hh"
|
||||
@@ -29,11 +31,19 @@ RealizeOnDomainOperation::RealizeOnDomainOperation(Context &context,
|
||||
|
||||
void RealizeOnDomainOperation::execute()
|
||||
{
|
||||
const Domain &in_domain = get_input().domain();
|
||||
|
||||
/* Even and odd-sized domains have different pixel locations, which produces unexpected
|
||||
* filtering. If one is odd and the other is even (detected by testing the low bit of the xor of
|
||||
* the sizes), shift the input by 1/2 pixel so the pixels align. */
|
||||
const float2 translation(((in_domain.size[0] ^ domain_.size[0]) & 1) ? -0.5f : 0.0f,
|
||||
((in_domain.size[1] ^ domain_.size[1]) & 1) ? -0.5f : 0.0f);
|
||||
|
||||
realize_on_domain(context(),
|
||||
get_input(),
|
||||
get_result(),
|
||||
domain_,
|
||||
get_input().domain().transformation,
|
||||
math::translate(in_domain.transformation, translation),
|
||||
get_input().get_realization_options());
|
||||
}
|
||||
|
||||
|
||||
@@ -20,11 +20,10 @@ void main()
|
||||
/* Since an input image with an identity transformation is supposed to be centered in the domain,
|
||||
* we subtract the offset between the lower left corners of the input image and the domain, which
|
||||
* is half the difference between their sizes, because the difference in size is on both sides of
|
||||
* the centered image. Additionally, we floor the offset to retain the 0.5 offset added above in
|
||||
* case the difference in sizes was odd. */
|
||||
* the centered image. */
|
||||
ivec2 domain_size = imageSize(domain_img);
|
||||
ivec2 input_size = texture_size(input_tx);
|
||||
vec2 offset = floor(vec2(domain_size - input_size) / 2.0);
|
||||
vec2 offset = vec2(domain_size - input_size) / 2.0;
|
||||
|
||||
/* Subtract the offset and divide by the input image size to get the relevant coordinates into
|
||||
* the sampler's expected [0, 1] range. */
|
||||
|
||||
Submodule tests/data updated: a480e3e75a...652394d339
Reference in New Issue
Block a user