Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/CMakeLists.txt5
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_symmetric_blur.glsl77
-rw-r--r--source/blender/gpu/shaders/compositor/compositor_symmetric_separable_blur.glsl53
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_symmetric_blur_info.hh13
-rw-r--r--source/blender/gpu/shaders/compositor/infos/compositor_symmetric_separable_blur_info.hh14
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_blur_common.glsl32
6 files changed, 194 insertions, 0 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 47d4feb7ec9..cb5bb4331f9 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -345,8 +345,11 @@ set(GLSL_SRC
shaders/compositor/compositor_screen_lens_distortion.glsl
shaders/compositor/compositor_set_alpha.glsl
shaders/compositor/compositor_split_viewer.glsl
+ shaders/compositor/compositor_symmetric_blur.glsl
+ shaders/compositor/compositor_symmetric_separable_blur.glsl
shaders/compositor/library/gpu_shader_compositor_alpha_over.glsl
+ shaders/compositor/library/gpu_shader_compositor_blur_common.glsl
shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl
shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl
shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl
@@ -620,6 +623,8 @@ set(SRC_SHADER_CREATE_INFOS
shaders/compositor/infos/compositor_screen_lens_distortion_info.hh
shaders/compositor/infos/compositor_set_alpha_info.hh
shaders/compositor/infos/compositor_split_viewer_info.hh
+ shaders/compositor/infos/compositor_symmetric_blur_info.hh
+ shaders/compositor/infos/compositor_symmetric_separable_blur_info.hh
)
set(SRC_SHADER_CREATE_INFOS_MTL
diff --git a/source/blender/gpu/shaders/compositor/compositor_symmetric_blur.glsl b/source/blender/gpu/shaders/compositor/compositor_symmetric_blur.glsl
new file mode 100644
index 00000000000..df08991a35c
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_symmetric_blur.glsl
@@ -0,0 +1,77 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_blur_common.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+vec4 load_input(ivec2 texel)
+{
+ vec4 color;
+ if (extend_bounds) {
+ /* If bounds are extended, then we treat the input as padded by a radius amount of pixels. So
+ * we load the input with an offset by the radius amount and fallback to a transparent color if
+ * it is out of bounds. Notice that we subtract 1 because the weights texture have an extra
+ * center weight, see the SymmetricBlurWeights for more information. */
+ ivec2 blur_size = texture_size(weights_tx) - 1;
+ color = texture_load(input_tx, texel - blur_size, vec4(0.0));
+ }
+ else {
+ color = texture_load(input_tx, texel);
+ }
+
+ if (gamma_correct) {
+ color = gamma_correct_blur_input(color);
+ }
+
+ return color;
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 accumulated_color = vec4(0.0);
+
+ /* First, compute the contribution of the center pixel. */
+ vec4 center_color = load_input(texel);
+ accumulated_color += center_color * texture_load(weights_tx, ivec2(0)).x;
+
+ ivec2 weights_size = texture_size(weights_tx);
+
+ /* Then, compute the contributions of the pixels along the x axis of the filter, noting that the
+ * weights texture only stores the weights for the positive half, but since the filter is
+ * symmetric, the same weight is used for the negative half and we add both of their
+ * contributions. */
+ for (int x = 1; x < weights_size.x; x++) {
+ float weight = texture_load(weights_tx, ivec2(x, 0)).x;
+ accumulated_color += load_input(texel + ivec2(x, 0)) * weight;
+ accumulated_color += load_input(texel + ivec2(-x, 0)) * weight;
+ }
+
+ /* Then, compute the contributions of the pixels along the y axis of the filter, noting that the
+ * weights texture only stores the weights for the positive half, but since the filter is
+ * symmetric, the same weight is used for the negative half and we add both of their
+ * contributions. */
+ for (int y = 1; y < weights_size.y; y++) {
+ float weight = texture_load(weights_tx, ivec2(0, y)).x;
+ accumulated_color += load_input(texel + ivec2(0, y)) * weight;
+ accumulated_color += load_input(texel + ivec2(0, -y)) * weight;
+ }
+
+ /* Finally, compute the contributions of the pixels in the four quadrants of the filter, noting
+ * that the weights texture only stores the weights for the upper right quadrant, but since the
+ * filter is symmetric, the same weight is used for the rest of the quadrants and we add all four
+ * of their contributions. */
+ for (int y = 1; y < weights_size.y; y++) {
+ for (int x = 1; x < weights_size.x; x++) {
+ float weight = texture_load(weights_tx, ivec2(x, y)).x;
+ accumulated_color += load_input(texel + ivec2(x, y)) * weight;
+ accumulated_color += load_input(texel + ivec2(-x, y)) * weight;
+ accumulated_color += load_input(texel + ivec2(x, -y)) * weight;
+ accumulated_color += load_input(texel + ivec2(-x, -y)) * weight;
+ }
+ }
+
+ if (gamma_correct) {
+ accumulated_color = gamma_uncorrect_blur_output(accumulated_color);
+ }
+
+ imageStore(output_img, texel, accumulated_color);
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_symmetric_separable_blur.glsl b/source/blender/gpu/shaders/compositor/compositor_symmetric_separable_blur.glsl
new file mode 100644
index 00000000000..ab0c7baa787
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_symmetric_separable_blur.glsl
@@ -0,0 +1,53 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_blur_common.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+vec4 load_input(ivec2 texel)
+{
+ vec4 color;
+ if (extend_bounds) {
+ /* If bounds are extended, then we treat the input as padded by a radius amount of pixels. So
+ * we load the input with an offset by the radius amount and fallback to a transparent color if
+ * it is out of bounds. Notice that we subtract 1 because the weights texture have an extra
+ * center weight, see the SymmetricSeparableBlurWeights for more information. */
+ int blur_size = texture_size(weights_tx) - 1;
+ color = texture_load(input_tx, texel - ivec2(blur_size, 0), vec4(0.0));
+ }
+ else {
+ color = texture_load(input_tx, texel);
+ }
+
+ if (gamma_correct_input) {
+ color = gamma_correct_blur_input(color);
+ }
+
+ return color;
+}
+
+void main()
+{
+ ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+ vec4 accumulated_color = vec4(0.0);
+
+ /* First, compute the contribution of the center pixel. */
+ vec4 center_color = load_input(texel);
+ accumulated_color += center_color * texture_load(weights_tx, 0).x;
+
+ /* Then, compute the contributions of the pixel to the right and left, noting that the
+ * weights texture only stores the weights for the positive half, but since the filter is
+ * symmetric, the same weight is used for the negative half and we add both of their
+ * contributions. */
+ for (int i = 1; i < texture_size(weights_tx); i++) {
+ float weight = texture_load(weights_tx, i).x;
+ accumulated_color += load_input(texel + ivec2(i, 0)) * weight;
+ accumulated_color += load_input(texel + ivec2(-i, 0)) * weight;
+ }
+
+ if (gamma_uncorrect_output) {
+ accumulated_color = gamma_uncorrect_blur_output(accumulated_color);
+ }
+
+ /* Write the color using the transposed texel. See the execute_separable_blur_horizontal_pass
+ * method for more information on the rational behind this. */
+ imageStore(output_img, texel.yx, accumulated_color);
+}
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_blur_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_blur_info.hh
new file mode 100644
index 00000000000..8ba2b4e04ef
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_blur_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_symmetric_blur)
+ .local_group_size(16, 16)
+ .push_constant(Type::BOOL, "extend_bounds")
+ .push_constant(Type::BOOL, "gamma_correct")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_2D, "weights_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_symmetric_blur.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_separable_blur_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_separable_blur_info.hh
new file mode 100644
index 00000000000..57247dba4b8
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_symmetric_separable_blur_info.hh
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_symmetric_separable_blur)
+ .local_group_size(16, 16)
+ .push_constant(Type::BOOL, "extend_bounds")
+ .push_constant(Type::BOOL, "gamma_correct_input")
+ .push_constant(Type::BOOL, "gamma_uncorrect_output")
+ .sampler(0, ImageType::FLOAT_2D, "input_tx")
+ .sampler(1, ImageType::FLOAT_1D, "weights_tx")
+ .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+ .compute_source("compositor_symmetric_separable_blur.glsl")
+ .do_static_compilation(true);
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_blur_common.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_blur_common.glsl
new file mode 100644
index 00000000000..e404c03bbb0
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_blur_common.glsl
@@ -0,0 +1,32 @@
+/* Preprocess the input of the blur filter by squaring it in its alpha straight form, assuming the
+ * given color is alpha premultiplied. */
+vec4 gamma_correct_blur_input(vec4 color)
+{
+ /* Unpremultiply alpha. */
+ color.rgb /= color.a > 0.0 ? color.a : 1.0;
+
+ /* Square color channel if it is positive, otherwise zero it. */
+ color.rgb *= mix(color.rgb, vec3(0.0), lessThan(color.rgb, vec3(0.0)));
+
+ /* Premultiply alpha to undo previous alpha unpremultiplication. */
+ color.rgb *= color.a > 0.0 ? color.a : 1.0;
+
+ return color;
+}
+
+/* Postprocess the output of the blur filter by taking its square root it in its alpha straight
+ * form, assuming the given color is alpha premultiplied. This essential undoes the processing done
+ * by the gamma_correct_blur_input function. */
+vec4 gamma_uncorrect_blur_output(vec4 color)
+{
+ /* Unpremultiply alpha. */
+ color.rgb /= color.a > 0.0 ? color.a : 1.0;
+
+ /* Take the square root of the color channel if it is positive, otherwise zero it. */
+ color.rgb = mix(sqrt(color.rgb), vec3(0.0), lessThan(color.rgb, vec3(0.0)));
+
+ /* Premultiply alpha to undo previous alpha unpremultiplication. */
+ color.rgb *= color.a > 0.0 ? color.a : 1.0;
+
+ return color;
+}