Compositor: Unify Defocus node between CPU and GPU

This patch unifies the Defocus node between the CPU and GPU compositors.
Both nodes now use a variable sized bokeh kernel which is always odd
sized for a center pixel guarantee. Further the CPU implementation now
properly handles half pixel offsets when doing interpolation, and always
sets the threshold to zero similar to the GPU implementation.
This commit is contained in:
Omar Emara
2024-03-28 14:35:13 +02:00
parent b115557883
commit db13fc01ad
4 changed files with 7 additions and 7 deletions
@@ -91,6 +91,7 @@ void DefocusNode::convert_to_operations(NodeConverter &converter,
BokehImageOperation *bokeh = new BokehImageOperation();
bokeh->set_data(bokehdata);
bokeh->set_resolution(math::ceil(data->maxblur) * 2 + 1);
bokeh->delete_data_on_finish();
converter.add_operation(bokeh);
@@ -101,7 +102,7 @@ void DefocusNode::convert_to_operations(NodeConverter &converter,
VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation();
operation->set_quality(eCompositorQuality::High);
operation->set_max_blur(data->maxblur);
operation->set_threshold(data->bthresh);
operation->set_threshold(0.0f);
converter.add_operation(operation);
converter.add_link(bokeh->get_output_socket(), operation->get_input_socket(1));
@@ -87,7 +87,6 @@ void VariableSizeBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *
const float base_size = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
const float maximum_size = size_buffer->get_max_value();
const int search_radius = math::clamp(int(maximum_size * base_size), 0, max_blur_);
const int2 bokeh_size = int2(bokeh_buffer->get_width(), bokeh_buffer->get_height());
BuffersIterator<float> it = output->iterate_with({}, area);
for (; !it.is_end(); ++it) {
@@ -115,8 +114,8 @@ void VariableSizeBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *
}
const float2 normalized_texel = (float2(xi, yi) + size + 0.5f) / (size * 2.0f + 1.0f);
const float2 weight_texel = (1.0f - normalized_texel) * float2(bokeh_size - 1);
const float4 weight = bokeh_buffer->get_elem(int(weight_texel.x), int(weight_texel.y));
const float2 weight_texel = 1.0f - normalized_texel;
const float4 weight = bokeh_buffer->texture_bilinear_extend(weight_texel);
const float4 color = input_buffer->get_elem_clamped(it.x + xi, it.y + yi);
accumulated_color += color * weight;
accumulated_weight += weight;
@@ -115,12 +115,12 @@ class DefocusOperation : public NodeOperation {
Result radius = compute_defocus_radius();
const int maximum_defocus_radius = compute_maximum_defocus_radius();
const int maximum_defocus_radius = math::ceil(compute_maximum_defocus_radius());
/* The special zero value indicate a circle, in which case, the roundness should be set to
* 1, and the number of sides can be anything and is arbitrarily set to 3. */
const bool is_circle = node_storage(bnode()).bktype == 0;
const int2 kernel_size = int2(maximum_defocus_radius * 2);
const int2 kernel_size = int2(maximum_defocus_radius * 2 + 1);
const int sides = is_circle ? 3 : node_storage(bnode()).bktype;
const float rotation = node_storage(bnode()).rotation;
const float roundness = is_circle ? 1.0f : 0.0f;