Fix #109868: Keying node differ between GPU and CPU
The Keying node produces different mattes between the GPU and CPU evaluators. That's because the CPU implementation doesn't use the full argmax to determine indices, rather, it only considers the first argmax and uses the minimum and maximum of the other two as a form of determinism or stability. The algorithm seems arbitrary and makes little sense to me, so for now, the CPU implementation was ported for consistent results.
This commit is contained in:
@@ -2,10 +2,19 @@
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
||||
|
||||
float compute_saturation(vec4 color, ivec3 argmax)
|
||||
ivec3 compute_saturation_indices(vec3 v)
|
||||
{
|
||||
float weighted_average = mix(color[argmax.y], color[argmax.z], key_balance);
|
||||
return (color[argmax.x] - weighted_average) * abs(1.0 - weighted_average);
|
||||
int index_of_max = ((v.x > v.y) ? ((v.x > v.z) ? 0 : 2) : ((v.y > v.z) ? 1 : 2));
|
||||
ivec2 other_indices = ivec2(mod(ivec2(index_of_max) + ivec2(1, 2), ivec2(3)));
|
||||
int min_index = min(other_indices.x, other_indices.y);
|
||||
int max_index = max(other_indices.x, other_indices.y);
|
||||
return ivec3(index_of_max, max_index, min_index);
|
||||
}
|
||||
|
||||
float compute_saturation(vec4 color, ivec3 indices)
|
||||
{
|
||||
float weighted_average = mix(color[indices.y], color[indices.z], key_balance);
|
||||
return (color[indices.x] - weighted_average) * abs(1.0 - weighted_average);
|
||||
}
|
||||
|
||||
void main()
|
||||
@@ -22,9 +31,9 @@ void main()
|
||||
}
|
||||
|
||||
vec4 key_color = texture_load(key_tx, texel);
|
||||
ivec3 key_argmax = argmax(key_color.rgb);
|
||||
float input_saturation = compute_saturation(input_color, key_argmax);
|
||||
float key_saturation = compute_saturation(key_color, key_argmax);
|
||||
ivec3 key_saturation_indices = compute_saturation_indices(key_color.rgb);
|
||||
float input_saturation = compute_saturation(input_color, key_saturation_indices);
|
||||
float key_saturation = compute_saturation(key_color, key_saturation_indices);
|
||||
|
||||
float matte = 1.0f - clamp(input_saturation / key_saturation, 0.0, 1.0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user