Blender V4.3
COM_SymmetricSeparableBlurVariableSizeAlgorithm.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_index_range.hh"
6#include "BLI_math_base.hh"
7#include "BLI_task.hh"
8
9#include "DNA_scene_types.h"
10
11#include "RE_pipeline.h"
12
13#include "COM_MemoryBuffer.h"
15
16namespace blender::compositor {
17
19{
20 const int size = math::ceil(radius) + 1;
21 rcti rect;
22 BLI_rcti_init(&rect, 0, size, 0, 1);
24
25 float sum = 0.0f;
26
27 const float center_weight = RE_filter_value(type, 0.0f);
28 *weights.get_elem(0, 0) = center_weight;
29 sum += center_weight;
30
31 const float scale = radius > 0.0f ? 1.0f / radius : 0.0f;
32 for (const int i : IndexRange(size).drop_front(1)) {
33 const float weight = RE_filter_value(type, i * scale);
34 *weights.get_elem(i, 0) = weight;
35 sum += weight * 2.0f;
36 }
37
38 for (const int i : IndexRange(size)) {
39 *weights.get_elem(i, 0) /= sum;
40 }
41
42 return weights;
43}
44
45static float sample_weight(const MemoryBuffer &weights, float parameter)
46{
47 const int size = weights.get_width();
48 float weight;
49 weights.read_elem_bilinear(parameter * size, 0.0f, &weight);
50 return weight;
51}
52
53static void blur_pass(const MemoryBuffer &input,
54 const MemoryBuffer &radius_buffer,
55 const MemoryBuffer &weights,
56 MemoryBuffer &output,
57 bool is_vertical)
58{
59 const int2 size = int2(input.get_width(), input.get_height());
60 threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) {
61 for (const int64_t y : sub_y_range) {
62 for (const int64_t x : IndexRange(size.x)) {
63 float accumulated_weight = 0.0f;
64 float4 accumulated_color = float4(0.0f);
65
66 float4 center_color = float4(input.get_elem(x, y));
67 float center_weight = *weights.get_elem(0, 0);
68 accumulated_color += center_color * center_weight;
69 accumulated_weight += center_weight;
70
71 int radius = int(
72 *(is_vertical ? radius_buffer.get_elem(y, x) : radius_buffer.get_elem(x, y)));
73
74 for (int i = 1; i <= radius; i++) {
75 float weight = sample_weight(weights, (float(i) + 0.5f) / float(radius + 1));
76 accumulated_color += float4(input.get_elem_clamped(x + i, y)) * weight;
77 accumulated_color += float4(input.get_elem_clamped(x - i, y)) * weight;
78 accumulated_weight += weight * 2.0f;
79 }
80
81 const float4 final_color = accumulated_color / accumulated_weight;
82 copy_v4_v4(output.get_elem(y, x), final_color);
83 }
84 }
85 });
86}
87
89 MemoryBuffer &output,
90 const MemoryBuffer &radius,
91 int filter_type,
92 int weights_resolution)
93{
95 weights_resolution);
96 rcti rect;
97 BLI_rcti_init(&rect, 0, input.get_height(), 0, input.get_width());
98 MemoryBuffer horizontal_pass_result = MemoryBuffer(DataType::Color, rect);
99
100 blur_pass(input, radius, weights, horizontal_pass_result, false);
101 blur_pass(horizontal_pass_result, radius, weights, output, true);
102}
103
104} // namespace blender::compositor
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition rct.c:418
static T sum(const btAlignedObjectArray< T > &items)
constexpr IndexRange drop_front(int64_t n) const
a MemoryBuffer contains access to the data
const int get_width() const
get the width of this MemoryBuffer
void read_elem_bilinear(float x, float y, float *out) const
float RE_filter_value(int type, float x)
static void blur_pass(const MemoryBuffer &input, const MemoryBuffer &radius_buffer, const MemoryBuffer &weights, MemoryBuffer &output, bool is_vertical)
static MemoryBuffer compute_symmetric_separable_blur_weights(int type, float radius)
void symmetric_separable_blur_variable_size(const MemoryBuffer &input, MemoryBuffer &output, const MemoryBuffer &radius, int filter_type, int weights_resolution)
static float sample_weight(const MemoryBuffer &weights, float parameter)
T ceil(const T &a)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:95
VecBase< int32_t, 2 > int2