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:
@@ -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;
|
||||
|
||||
+1
-1
Submodule tests/data updated: 1b1cbfd788...acedb61381
Reference in New Issue
Block a user