Blender V4.3
COM_GaussianAlphaBlurBaseOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7namespace blender::compositor {
8
11{
12 gausstab_ = nullptr;
13 filtersize_ = 0;
14 falloff_ = -1; /* Intentionally invalid, so we can detect uninitialized values. */
15 dimension_ = dim;
16}
17
25
32
47
49 const rcti &output_area,
50 rcti &r_input_area)
51{
52 if (input_idx != IMAGE_INPUT_INDEX) {
53 BlurBaseOperation::get_area_of_interest(input_idx, output_area, r_input_area);
54 return;
55 }
56
57 r_input_area = output_area;
58 switch (dimension_) {
59 case eDimension::X:
60 r_input_area.xmin = output_area.xmin - filtersize_ - 1;
61 r_input_area.xmax = output_area.xmax + filtersize_ + 1;
62 break;
63 case eDimension::Y:
64 r_input_area.ymin = output_area.ymin - filtersize_ - 1;
65 r_input_area.ymax = output_area.ymax + filtersize_ + 1;
66 break;
67 }
68}
69
71 const rcti &area,
73{
74 MemoryBuffer *input = inputs[IMAGE_INPUT_INDEX];
75 const rcti &input_rect = input->get_rect();
76 BuffersIterator<float> it = output->iterate_with({input}, area);
77
78 int min_input_coord = -1;
79 int max_input_coord = -1;
80 int elem_stride = -1;
81 std::function<int()> get_current_coord;
82 switch (dimension_) {
83 case eDimension::X:
84 min_input_coord = input_rect.xmin;
85 max_input_coord = input_rect.xmax;
86 get_current_coord = [&] { return it.x; };
87 elem_stride = input->elem_stride;
88 break;
89 case eDimension::Y:
90 min_input_coord = input_rect.ymin;
91 max_input_coord = input_rect.ymax;
92 get_current_coord = [&] { return it.y; };
93 elem_stride = input->row_stride;
94 break;
95 }
96
97 for (; !it.is_end(); ++it) {
98 const int coord = get_current_coord();
99 const int coord_min = max_ii(coord - filtersize_, min_input_coord);
100 const int coord_max = min_ii(coord + filtersize_ + 1, max_input_coord);
101
102 /* *** This is the main part which is different to #GaussianBlurBaseOperation. *** */
103 /* Gauss. */
104 float alpha_accum = 0.0f;
105 float multiplier_accum = 0.0f;
106
107 /* Dilate. */
108 const bool do_invert = do_subtract_;
109 /* Init with the current color to avoid unneeded lookups. */
110 float value_max = finv_test(*it.in(0), do_invert);
111 float distfacinv_max = 1.0f; /* 0 to 1 */
112
113 const float *in = it.in(0) + (intptr_t(coord_min) - coord) * elem_stride;
114 const int in_stride = elem_stride;
115 int index = (coord_min - coord) + filtersize_;
116 const int index_end = index + (coord_max - coord_min);
117 for (; index < index_end; in += in_stride, ++index) {
118 float value = finv_test(*in, do_invert);
119
120 /* Gauss. */
121 float multiplier = gausstab_[index];
122 alpha_accum += value * multiplier;
123 multiplier_accum += multiplier;
124
125 /* Dilate - find most extreme color. */
126 if (value > value_max) {
127 multiplier = distbuf_inv_[index];
128 value *= multiplier;
129 if (value > value_max) {
130 value_max = value;
131 distfacinv_max = multiplier;
132 }
133 }
134 }
135
136 /* Blend between the max value and gauss blue - gives nice feather. */
137 const float value_blur = alpha_accum / multiplier_accum;
138 const float value_final = (value_max * distfacinv_max) +
139 (value_blur * (1.0f - distfacinv_max));
140 *it.out = finv_test(value_final, do_invert);
141 }
142}
143
144} // namespace blender::compositor
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
#define MAX_GAUSSTAB_RADIUS
virtual void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
float * make_dist_fac_inverse(float rad, int size, int falloff)
BLI_INLINE float finv_test(const float f, const bool test)
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) final
Get input operation area being read by this operation on rendering given output area.
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) final
a MemoryBuffer contains access to the data
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
DataType
possible data types for sockets
Definition COM_defines.h:21
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
ccl_device_inline float3 ceil(const float3 a)
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
_W64 int intptr_t
Definition stdint.h:118
int ymin
int ymax
int xmin
int xmax