22template<
typename T,
bool ExtendBounds>
31 auto load_input = [&](
const int2 texel) {
33 if constexpr (ExtendBounds) {
37 color =
input.load_pixel_zero<
T>(texel - blur_radius);
50 T accumulated_color =
T(0);
53 T center_color = load_input(texel);
54 accumulated_color += center_color * weights.
load_pixel<
float>(
int2(0));
62 accumulated_color += load_input(texel +
int2(
i, 0)) * weight;
63 accumulated_color += load_input(texel +
int2(-
i, 0)) * weight;
68 output.store_pixel(
int2(texel.y, texel.x), accumulated_color);
76 return "compositor_symmetric_separable_blur_float";
78 return "compositor_symmetric_separable_blur_float4";
90 const int filter_type,
91 const bool extend_bounds)
98 input.bind_as_texture(shader,
"input_tx");
100 const Result &weights = context.cache_manager().symmetric_separable_blur_weights.get(
101 context, filter_type, radius);
120 output.allocate_texture(transposed_domain);
121 output.bind_as_image(shader,
"output_img");
126 input.unbind_as_texture();
136 const int filter_type,
137 const bool extend_bounds)
139 const Result &weights = context.cache_manager().symmetric_separable_blur_weights.get(
140 context, filter_type, radius);
158 output.allocate_texture(transposed_domain);
160 switch (
input.type()) {
188 const int filter_type,
189 const bool extend_bounds)
191 if (context.use_gpu()) {
198 const Result &original_input,
199 const Result &horizontal_pass_result,
202 const int filter_type,
203 const bool extend_bounds)
212 const Result &weights = context.cache_manager().symmetric_separable_blur_weights.get(
213 context, filter_type, radius.y);
222 output.allocate_texture(domain);
223 output.bind_as_image(shader,
"output_img");
236 const Result &original_input,
237 const Result &horizontal_pass_result,
240 const int filter_type,
241 const bool extend_bounds)
243 const Result &weights = context.cache_manager().symmetric_separable_blur_weights.get(
244 context, filter_type, radius.y);
251 output.allocate_texture(domain);
253 switch (original_input.
type()) {
277 const Result &original_input,
278 const Result &horizontal_pass_result,
281 const int filter_type,
282 const bool extend_bounds)
284 if (context.use_gpu()) {
287 horizontal_pass_result,
296 horizontal_pass_result,
308 const int filter_type,
309 const bool extend_bounds)
312 context,
input, radius.x, filter_type, extend_bounds);
315 context,
input, horizontal_pass_result,
output, radius, filter_type, extend_bounds);
317 horizontal_pass_result.
release();
#define BLI_assert_unreachable()
void GPU_shader_bind(GPUShader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void unbind_as_texture() const
static ResultType type(eGPUTextureFormat format)
void bind_as_texture(GPUShader *shader, const char *texture_name) const
const Domain & domain() const
T load_pixel(const int2 &texel) const
static void vertical_pass_cpu(Context &context, const Result &original_input, const Result &horizontal_pass_result, Result &output, const int distance, const int falloff_type)
void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, int2 local_size=int2(16))
void symmetric_separable_blur(Context &context, const Result &input, Result &output, const float2 &radius, const int filter_type=R_FILTER_GAUSS, const bool extend_bounds=false)
static void vertical_pass(Context &context, const Result &original_input, const Result &horizontal_pass_result, Result &output, const int distance, const int falloff_type)
static Result horizontal_pass_cpu(Context &context, const Result &input, const int distance, const int falloff_type)
static const char * get_blur_shader(const ResultType type)
static Result horizontal_pass_gpu(Context &context, const Result &input, const int distance, const int falloff_type)
static Result horizontal_pass(Context &context, const Result &input, const int distance, const int falloff_type)
void parallel_for(const int2 range, const Function &function)
static void vertical_pass_gpu(Context &context, const Result &original_input, const Result &horizontal_pass_result, Result &output, const int distance, const int falloff_type)
static void blur_pass(Context &context, const Result &input, Result &output, const float sigma)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2