Fix: Bokeh blur node flips its bokeh input

The bokeh blur node flipped its bokeh input due to the conceptual
difference between the search window space and the weights texture
space. This patches fixes that by inverting the weights texture to match
the search window.

The variable size option actually flips the bokeh input for the CPU
compositor. It is unclear if this is expected, so we deviate from that
behavior for now.
This commit is contained in:
Omar Emara 2022-10-21 14:05:19 +02:00
parent 26f181c6b7
commit 899d4ddbd0
2 changed files with 32 additions and 10 deletions

View File

@ -18,13 +18,24 @@ vec4 load_input(ivec2 texel)
}
/* Given the texel in the range [-radius, radius] in both axis, load the appropriate weight from
* the weights texture, where the texel (0, 0) is considered the center of weights texture. */
* the weights texture, where the given texel (0, 0) corresponds the center of weights texture.
* Note that we load the weights texture inverted along both directions to maintain the shape of
* the weights if it was not symmetrical. To understand why inversion makes sense, consider a 1D
* weights texture whose right half is all ones and whose left half is all zeros. Further, consider
* that we are blurring a single white pixel on a black background. When computing the value of a
* pixel that is to the right of the white pixel, the white pixel will be in the left region of the
* search window, and consequently, without inversion, a zero will be sampled from the left side of
* the weights texture and result will be zero. However, what we expect is that pixels to the right
* of the white pixel will be white, that is, they should sample a weight of 1 from the right side
* of the weights texture, hence the need for inversion. */
vec4 load_weight(ivec2 texel)
{
/* Add the radius to transform the texel into the range [0, radius * 2], then divide by the upper
* bound plus one to transform the texel into the normalized range [0, 1] needed to sample the
* weights sampler. Finally, also add 0.5 to sample at the center of the pixels. */
return texture(weights_tx, (texel + vec2(radius + 0.5)) / (radius * 2 + 1));
/* Add the radius to transform the texel into the range [0, radius * 2], with an additional 0.5
* to sample at the center of the pixels, then divide by the upper bound plus one to transform
* the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally,
* invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as
* mentioned in the function description. */
return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1)));
}
void main()

View File

@ -2,7 +2,16 @@
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
/* Given the texel in the range [-radius, radius] in both axis, load the appropriate weight from
* the weights texture, where the texel (0, 0) is considered the center of weights texture. */
* the weights texture, where the given texel (0, 0) corresponds the center of weights texture.
* Note that we load the weights texture inverted along both directions to maintain the shape of
* the weights if it was not symmetrical. To understand why inversion makes sense, consider a 1D
* weights texture whose right half is all ones and whose left half is all zeros. Further, consider
* that we are blurring a single white pixel on a black background. When computing the value of a
* pixel that is to the right of the white pixel, the white pixel will be in the left region of the
* search window, and consequently, without inversion, a zero will be sampled from the left side of
* the weights texture and result will be zero. However, what we expect is that pixels to the right
* of the white pixel will be white, that is, they should sample a weight of 1 from the right side
* of the weights texture, hence the need for inversion. */
vec4 load_weight(ivec2 texel, float radius)
{
/* The center zero texel is always assigned a unit weight regardless of the corresponding weight
@ -12,10 +21,12 @@ vec4 load_weight(ivec2 texel, float radius)
return vec4(1.0);
}
/* Add the radius to transform the texel into the range [0, radius * 2], then divide by the upper
* bound plus one to transform the texel into the normalized range [0, 1] needed to sample the
* weights sampler. Finally, also add 0.5 to sample at the center of the pixels. */
return texture(weights_tx, (texel + vec2(radius + 0.5)) / (radius * 2 + 1));
/* Add the radius to transform the texel into the range [0, radius * 2], with an additional 0.5
* to sample at the center of the pixels, then divide by the upper bound plus one to transform
* the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally,
* invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as
* mentioned in the function description. */
return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1)));
}
void main()