Compositor: Implement Morphological Blurring for CPU
Reference #125968.
This commit is contained in:
@@ -30,11 +30,12 @@ enum class MorphologicalBlurOperation : uint8_t {
|
||||
* and blurred input depending on the chosen operation, see the MorphologicalBlurOperation enum for
|
||||
* more information. The output is written to the given output result, which will be allocated
|
||||
* internally and is thus expected not to be previously allocated. */
|
||||
void morphological_blur(Context &context,
|
||||
Result &input,
|
||||
Result &output,
|
||||
float2 radius,
|
||||
MorphologicalBlurOperation operation = MorphologicalBlurOperation::Erode,
|
||||
int filter_type = R_FILTER_GAUSS);
|
||||
void morphological_blur(
|
||||
Context &context,
|
||||
const Result &input,
|
||||
Result &output,
|
||||
const float2 &radius,
|
||||
const MorphologicalBlurOperation operation = MorphologicalBlurOperation::Erode,
|
||||
const int filter_type = R_FILTER_GAUSS);
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_assert.h"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "GPU_shader.hh"
|
||||
@@ -23,20 +24,16 @@ static const char *get_shader(MorphologicalBlurOperation operation)
|
||||
return "compositor_morphological_blur_dilate";
|
||||
case MorphologicalBlurOperation::Erode:
|
||||
return "compositor_morphological_blur_erode";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Apply the morphological operator (minimum or maximum) on the input and the blurred input. The
|
||||
* output is written to the blurred_input in-place. */
|
||||
static void apply_morphological_operator(Context &context,
|
||||
Result &input,
|
||||
Result &blurred_input,
|
||||
MorphologicalBlurOperation operation)
|
||||
static void apply_morphological_operator_gpu(Context &context,
|
||||
const Result &input,
|
||||
Result &blurred_input,
|
||||
const MorphologicalBlurOperation operation)
|
||||
{
|
||||
GPUShader *shader = context.get_shader(get_shader(operation));
|
||||
GPU_shader_bind(shader);
|
||||
@@ -53,12 +50,50 @@ static void apply_morphological_operator(Context &context,
|
||||
blurred_input.unbind_as_image();
|
||||
}
|
||||
|
||||
static void apply_morphological_operator_cpu(const Result &input,
|
||||
Result &blurred_input,
|
||||
const MorphologicalBlurOperation operation)
|
||||
{
|
||||
Domain domain = input.domain();
|
||||
switch (operation) {
|
||||
case MorphologicalBlurOperation::Dilate:
|
||||
parallel_for(domain.size, [&](const int2 texel) {
|
||||
float input_value = input.load_pixel(texel).x;
|
||||
float blurred_value = blurred_input.load_pixel(texel).x;
|
||||
blurred_input.store_pixel(texel, float4(math::max(input_value, blurred_value)));
|
||||
});
|
||||
break;
|
||||
case MorphologicalBlurOperation::Erode:
|
||||
parallel_for(domain.size, [&](const int2 texel) {
|
||||
float input_value = input.load_pixel(texel).x;
|
||||
float blurred_value = blurred_input.load_pixel(texel).x;
|
||||
blurred_input.store_pixel(texel, float4(math::min(input_value, blurred_value)));
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply the morphological operator (minimum or maximum) on the input and the blurred input. The
|
||||
* output is written to the blurred_input in-place. */
|
||||
static void apply_morphological_operator(Context &context,
|
||||
const Result &input,
|
||||
Result &blurred_input,
|
||||
const MorphologicalBlurOperation operation)
|
||||
{
|
||||
if (context.use_gpu()) {
|
||||
apply_morphological_operator_gpu(context, input, blurred_input, operation);
|
||||
}
|
||||
else {
|
||||
apply_morphological_operator_cpu(input, blurred_input, operation);
|
||||
}
|
||||
}
|
||||
|
||||
void morphological_blur(Context &context,
|
||||
Result &input,
|
||||
const Result &input,
|
||||
Result &output,
|
||||
float2 radius,
|
||||
MorphologicalBlurOperation operation,
|
||||
int filter_type)
|
||||
const float2 &radius,
|
||||
const MorphologicalBlurOperation operation,
|
||||
const int filter_type)
|
||||
{
|
||||
BLI_assert(input.type() == ResultType::Float);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user