23 return "compositor_morphological_distance_dilate";
25 return "compositor_morphological_distance_erode";
39 input.bind_as_texture(shader,
"input_tx");
42 output.bind_as_image(shader,
"output_img");
48 input.unbind_as_texture();
51template<
bool IsDilate>
54 const int structuring_element_radius)
58 const float limit = IsDilate ? std::numeric_limits<float>::lowest() :
59 std::numeric_limits<float>::max();
60 const auto morphology_operator = [](
const float a,
const float b) {
61 if constexpr (IsDilate) {
69 const int2 image_size =
input.domain().size;
71 const int radius_squared =
math::square(structuring_element_radius);
81 const int2 start =
math::max(texel - structuring_element_radius,
int2(0)) - texel;
82 const int2 end =
math::min(texel + structuring_element_radius + 1, image_size) - texel;
85 for (
int y = start.y;
y < end.y;
y++) {
87 for (
int x = start.x;
x < end.x;
x++) {
88 if (
x *
x + yy > radius_squared) {
91 value = morphology_operator(value,
input.load_pixel<
float>(texel +
int2(
x,
y)));
95 output.store_pixel(texel, value);
104 if (context.use_gpu()) {
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_shader_uniform_1i(blender::gpu::Shader *sh, const char *name, int value)
float distance(VecOp< float, D >, VecOp< float, D >) RET
void compute_dispatch_threads_at_least(gpu::Shader *shader, int2 threads_range, int2 local_size=int2(16))
static void morphological_distance_cpu(const Result &input, Result &output, const int structuring_element_radius)
void morphological_distance(Context &context, const Result &input, Result &output, const int distance)
static void morphological_distance_gpu(Context &context, const Result &input, Result &output, const int distance)
void parallel_for(const int2 range, const Function &function)
static const char * get_shader_name(const int distance)
T min(const T &a, const T &b)
T max(const T &a, const T &b)
VecBase< int32_t, 2 > int2