22 const Result &first_causal_input,
23 const Result &first_non_causal_input,
24 const Result &second_causal_input,
25 const Result &second_non_causal_input,
28 gpu::Shader *shader = context.get_shader(
"compositor_van_vliet_gaussian_blur_sum");
32 first_non_causal_input.
bind_as_texture(shader,
"first_non_causal_input_tx");
34 second_non_causal_input.
bind_as_texture(shader,
"second_non_causal_input_tx");
38 output.allocate_texture(transposed_domain);
39 output.bind_as_image(shader,
"output_img");
53 const Result &first_non_causal_input,
54 const Result &second_causal_input,
55 const Result &second_non_causal_input,
60 output.allocate_texture(transposed_domain);
64 float4 filter_output = first_causal_input.load_pixel<float4>(texel) +
65 first_non_causal_input.load_pixel<float4>(texel) +
66 second_causal_input.load_pixel<float4>(texel) +
67 second_non_causal_input.load_pixel<float4>(texel);
71 output.store_pixel(int2(texel.y, texel.x), filter_output);
88 const Result &first_causal_input,
89 const Result &first_non_causal_input,
90 const Result &second_causal_input,
91 const Result &second_non_causal_input,
94 if (context.use_gpu()) {
97 first_non_causal_input,
99 second_non_causal_input,
104 first_non_causal_input,
106 second_non_causal_input,
113 Result &first_causal_result,
114 Result &first_non_causal_result,
115 Result &second_causal_result,
116 Result &second_non_causal_result,
119 gpu::Shader *shader = context.get_shader(
"compositor_van_vliet_gaussian_blur");
123 context.cache_manager().van_vliet_gaussian_coefficients.get(context, sigma);
128 "first_causal_feedforward_coefficients",
131 "first_non_causal_feedforward_coefficients",
136 "second_causal_feedforward_coefficients",
139 "second_non_causal_feedforward_coefficients",
142 "first_causal_boundary_coefficient",
145 "first_non_causal_boundary_coefficient",
148 "second_causal_boundary_coefficient",
151 "second_non_causal_boundary_coefficient",
154 input.bind_as_texture(shader,
"input_tx");
159 first_causal_result.
bind_as_image(shader,
"first_causal_output_img");
162 first_non_causal_result.
bind_as_image(shader,
"first_non_causal_output_img");
165 second_causal_result.
bind_as_image(shader,
"second_causal_output_img");
168 second_non_causal_result.
bind_as_image(shader,
"second_non_causal_output_img");
176 input.unbind_as_texture();
185 Result &first_causal_output,
186 Result &first_non_causal_output,
187 Result &second_causal_output,
188 Result &second_non_causal_output,
192 context.cache_manager().van_vliet_gaussian_coefficients.get(context, sigma);
195 const float2 first_causal_feedforward_coefficients =
float2(
197 const float2 first_non_causal_feedforward_coefficients =
float2(
200 const float2 second_causal_feedforward_coefficients =
float2(
202 const float2 second_non_causal_feedforward_coefficients =
float2(
204 const float first_causal_boundary_coefficient =
float(
206 const float first_non_causal_boundary_coefficient =
float(
208 const float second_causal_boundary_coefficient =
float(
210 const float second_non_causal_boundary_coefficient =
float(
237 int y = invocation.y;
238 int width =
input.domain().size.x;
248 bool is_causal = invocation.x % 2 == 0;
249 float2 first_feedforward_coefficients = is_causal ? first_causal_feedforward_coefficients :
250 first_non_causal_feedforward_coefficients;
251 float first_boundary_coefficient = is_causal ? first_causal_boundary_coefficient :
252 first_non_causal_boundary_coefficient;
253 float2 second_feedforward_coefficients = is_causal ?
254 second_causal_feedforward_coefficients :
255 second_non_causal_feedforward_coefficients;
256 float second_boundary_coefficient = is_causal ? second_causal_boundary_coefficient :
257 second_non_causal_boundary_coefficient;
259 bool is_first_filter = invocation.x < 2;
260 float2 feedforward_coefficients = is_first_filter ? first_feedforward_coefficients :
261 second_feedforward_coefficients;
262 float2 feedback_coefficients = is_first_filter ? first_feedback_coefficients :
263 second_feedback_coefficients;
264 float boundary_coefficient = is_first_filter ? first_boundary_coefficient :
265 second_boundary_coefficient;
270 int2 boundary_texel = is_causal ?
int2(0,
y) :
int2(width - 1,
y);
279 float4 output_boundary = input_boundary * boundary_coefficient;
282 for (
int x = 0;
x < width;
x++) {
299 int first_input_index = is_causal ? 0 : 1;
301 outputs[0] += feedforward_coefficients[
i] *
inputs[first_input_index +
i];
308 if (is_first_filter) {
316 if (is_first_filter) {
348 if (context.use_gpu()) {
352 first_non_causal_result,
353 second_causal_result,
354 second_non_causal_result,
361 first_non_causal_result,
362 second_causal_result,
363 second_non_causal_result,
369 first_non_causal_result,
370 second_causal_result,
371 second_non_causal_result,
374 first_non_causal_result.
release();
375 second_causal_result.
release();
376 second_non_causal_result.
release();
385 "Van Vliet filter is less accurate for sigma values less than 32. Use Deriche "
386 "filter instead or direct convolution instead.");
391 horizontal_pass_result.
release();
#define BLI_assert_msg(a, msg)
void GPU_shader_uniform_1f(blender::gpu::Shader *sh, const char *name, float value)
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_shader_uniform_2fv(blender::gpu::Shader *sh, const char *name, const float data[2])
Domain transposed() const
void store_pixel(const int2 &texel, const T &pixel_value)
void allocate_texture(const Domain domain, const bool from_pool=true, const std::optional< ResultStorageType > storage_type=std::nullopt)
void unbind_as_texture() const
void bind_as_texture(gpu::Shader *shader, const char *texture_name) const
const Domain & domain() const
void unbind_as_image() const
void bind_as_image(gpu::Shader *shader, const char *image_name, bool read=false) const
double first_non_causal_boundary_coefficient() const
const double2 & second_non_causal_feedforward_coefficients() const
double second_non_causal_boundary_coefficient() const
const double2 & second_feedback_coefficients() const
const double2 & second_causal_feedforward_coefficients() const
const double2 & first_feedback_coefficients() const
double second_causal_boundary_coefficient() const
const double2 & first_non_causal_feedforward_coefficients() const
double first_causal_boundary_coefficient() const
const double2 & first_causal_feedforward_coefficients() const
static void sum_causal_and_non_causal_results_cpu(const Result &causal_input, const Result &non_causal_input, Result &output)
void compute_dispatch_threads_at_least(gpu::Shader *shader, int2 threads_range, int2 local_size=int2(16))
static void sum_causal_and_non_causal_results(Context &context, const Result &causal_input, const Result &non_causal_input, Result &output)
static void blur_pass_cpu(Context &context, const Result &input, Result &causal_output, Result &non_causal_output, const float sigma)
void van_vliet_gaussian_blur(Context &context, const Result &input, Result &output, const float2 &sigma)
void parallel_for(const int2 range, const Function &function)
static void blur_pass_gpu(Context &context, const Result &input, Result &causal_result, Result &non_causal_result, const float sigma)
static void sum_causal_and_non_causal_results_gpu(Context &context, const Result &causal_input, const Result &non_causal_input, Result &output)
static void blur_pass(Context &context, const Result &input, Result &output, const float sigma)
T reduce_max(const VecBase< T, Size > &a)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
static blender::bke::bNodeSocketTemplate outputs[]
static blender::bke::bNodeSocketTemplate inputs[]