18#ifdef COM_DEFOCUS_SEARCH
27 do_size_scale_ =
false;
39 const rcti &output_area,
43 case IMAGE_INPUT_INDEX:
44 case BOUNDING_BOX_INPUT_INDEX:
45 case SIZE_INPUT_INDEX: {
47 const float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
48 const int max_blur_scalar = max_blur_ * scalar;
49 r_input_area.
xmax = output_area.
xmax + max_blur_scalar + 2;
50 r_input_area.
xmin = output_area.
xmin - max_blur_scalar - 2;
51 r_input_area.
ymax = output_area.
ymax + max_blur_scalar + 2;
52 r_input_area.
ymin = output_area.
ymin - max_blur_scalar - 2;
55 case BOKEH_INPUT_INDEX: {
56 r_input_area = output_area;
61#ifdef COM_DEFOCUS_SEARCH
62 case DEFOCUS_INPUT_INDEX: {
63 r_input_area.
xmax = (output_area.
xmax / InverseSearchRadiusOperation::DIVIDER) + 1;
64 r_input_area.
xmin = (output_area.
xmin / InverseSearchRadiusOperation::DIVIDER) - 1;
65 r_input_area.
ymax = (output_area.
ymax / InverseSearchRadiusOperation::DIVIDER) + 1;
66 r_input_area.
ymin = (output_area.
ymin / InverseSearchRadiusOperation::DIVIDER) - 1;
83 const float base_size = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
85 const int search_radius =
math::clamp(
int(maximum_size * base_size), 0, max_blur_);
88 for (; !it.is_end(); ++it) {
89 if (*mask_buffer->
get_elem(it.x, it.y) <= 0.0f) {
94 const float center_size =
math::max(0.0f, *size_buffer->
get_elem(it.x, it.y) * base_size);
98 if (center_size >= threshold_) {
99 for (
int yi = -search_radius; yi <= search_radius; ++yi) {
100 for (
int xi = -search_radius; xi <= search_radius; ++xi) {
101 if (xi == 0 && yi == 0) {
106 const float size =
math::min(center_size, candidate_size);
111 const float2 normalized_texel = (
float2(xi, yi) + size + 0.5f) / (size * 2.0f + 1.0f);
112 const float2 weight_texel = 1.0f - normalized_texel;
115 accumulated_color += color * weight;
116 accumulated_weight += weight;
125 if ((center_size > threshold_) && (center_size < threshold_ * 2.0f)) {
127 float fac = (center_size - threshold_) / threshold_;
133#ifdef COM_DEFOCUS_SEARCH
135InverseSearchRadiusOperation::InverseSearchRadiusOperation()
141void InverseSearchRadiusOperation::determine_resolution(
uint resolution[2],
142 uint preferred_resolution[2])
144 NodeOperation::determine_resolution(resolution, preferred_resolution);
145 resolution[0] = resolution[0] / DIVIDER;
146 resolution[1] = resolution[1] / DIVIDER;
MINLINE void copy_v4_v4(float r[4], const float a[4])
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], float t)
a MemoryBuffer contains access to the data
const float * get_elem_clamped(int x, int y) const
float get_max_value() const
float * get_elem(int x, int y)
float4 texture_bilinear_extend(float2 coordinates) const
unsigned int get_height() const
void add_output_socket(DataType datatype)
unsigned int get_width() const
NodeOperationFlags flags_
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
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.
VariableSizeBokehBlurOperation()
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
constexpr float COM_BLUR_BOKEH_PIXELS
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
T clamp(const T &a, const T &min, const T &max)
T safe_divide(const T &a, const T &b)
T min(const T &a, const T &b)
T max(const T &a, const T &b)
VecBase< float, 4 > float4
VecBase< float, 2 > float2