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:
authorOmar Emara <mail@OmarEmara.dev>2022-08-10 11:21:18 +0300
committerOmar Emara <mail@OmarEmara.dev>2022-08-10 11:21:18 +0300
commitc014021802c323c3ed55c3c283717975a3d93edf (patch)
treea2537ce8187e6acff56b3936d994ab73447b3ad0 /source/blender/gpu/shaders/compositor/library
parentb5df7a02ac754de8e04fdeda4d1c3f0fcdf6a7a2 (diff)
Realtime Compositor: Add basic matte nodes
This patch implements the following nodes for the realtime compositor: - Box mask node. - Channel matte node. - Chroma matte node. - Color matte node. - Color spill node. - Difference matte node. - Distance matte node. - Ellipse matte node. - Luminance matte node. Differential Revision: https://developer.blender.org/D15230 Reviewed By: Clement Foucault
Diffstat (limited to 'source/blender/gpu/shaders/compositor/library')
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl52
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl43
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl27
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl13
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl10
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl26
-rw-r--r--source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl14
7 files changed, 185 insertions, 0 deletions
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl
new file mode 100644
index 00000000000..f2dcc9543f2
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_channel_matte.glsl
@@ -0,0 +1,52 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+#define CMP_NODE_CHANNEL_MATTE_CS_RGB 1.0
+#define CMP_NODE_CHANNEL_MATTE_CS_HSV 2.0
+#define CMP_NODE_CHANNEL_MATTE_CS_YUV 3.0
+#define CMP_NODE_CHANNEL_MATTE_CS_YCC 4.0
+
+void node_composite_channel_matte(vec4 color,
+ const float color_space,
+ const float matte_channel,
+ const vec2 limit_channels,
+ float max_limit,
+ float min_limit,
+ out vec4 result,
+ out float matte)
+{
+ vec4 channels;
+ if (color_space == CMP_NODE_CHANNEL_MATTE_CS_HSV) {
+ rgb_to_hsv(color, channels);
+ }
+ else if (color_space == CMP_NODE_CHANNEL_MATTE_CS_YUV) {
+ rgba_to_yuva_itu_709(color, channels);
+ }
+ else if (color_space == CMP_NODE_CHANNEL_MATTE_CS_YCC) {
+ rgba_to_ycca_itu_709(color, channels);
+ }
+ else {
+ channels = color;
+ }
+
+ float matte_value = channels[int(matte_channel)];
+ float limit_value = max(channels[int(limit_channels.x)], channels[int(limit_channels.y)]);
+
+ float alpha = 1.0 - (matte_value - limit_value);
+ if (alpha > max_limit) {
+ alpha = color.a;
+ }
+ else if (alpha < min_limit) {
+ alpha = 0.0;
+ }
+ else {
+ alpha = (alpha - min_limit) / (max_limit - min_limit);
+ }
+
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
+
+#undef CMP_NODE_CHANNEL_MATTE_CS_RGB
+#undef CMP_NODE_CHANNEL_MATTE_CS_HSV
+#undef CMP_NODE_CHANNEL_MATTE_CS_YUV
+#undef CMP_NODE_CHANNEL_MATTE_CS_YCC
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl
new file mode 100644
index 00000000000..5d6bea0c9db
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_chroma_matte.glsl
@@ -0,0 +1,43 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* Algorithm from the book Video Demystified. Chapter 7. Chroma Keying. */
+void node_composite_chroma_matte(vec4 color,
+ vec4 key,
+ float acceptance,
+ float cutoff,
+ float falloff,
+ out vec4 result,
+ out float matte)
+{
+ vec4 color_ycca;
+ rgba_to_ycca_itu_709(color, color_ycca);
+ vec4 key_ycca;
+ rgba_to_ycca_itu_709(key, key_ycca);
+
+ /* Normalize the CrCb components into the [-1, 1] range. */
+ vec2 color_cc = color_ycca.yz * 2.0 - 1.0;
+ vec2 key_cc = key_ycca.yz * 2.0 - 1.0;
+
+ /* Rotate the color onto the space of the key such that x axis of the color space passes through
+ * the key color. */
+ color_cc = vector_to_rotation_matrix(key_cc * vec2(1.0, -1.0)) * color_cc;
+
+ /* Compute foreground key. If positive, the value is in the [0, 1] range. */
+ float foreground_key = color_cc.x - (abs(color_cc.y) / acceptance);
+
+ /* Negative foreground key values retain the original alpha. Positive values are scaled by the
+ * falloff, while colors that make an angle less than the cutoff angle get a zero alpha. */
+ float alpha = color.a;
+ if (foreground_key > 0.0) {
+ alpha = 1.0 - (foreground_key / falloff);
+
+ if (abs(atan(color_cc.y, color_cc.x)) < (cutoff / 2.0)) {
+ alpha = 0.0;
+ }
+ }
+
+ /* Compute output. */
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl
new file mode 100644
index 00000000000..038471bc1bc
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_matte.glsl
@@ -0,0 +1,27 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_color_matte(vec4 color,
+ vec4 key,
+ float hue_epsilon,
+ float saturation_epsilon,
+ float value_epsilon,
+ out vec4 result,
+ out float matte)
+
+{
+ vec4 color_hsva;
+ rgb_to_hsv(color, color_hsva);
+ vec4 key_hsva;
+ rgb_to_hsv(key, key_hsva);
+
+ bool is_within_saturation = distance(color_hsva.y, key_hsva.y) < saturation_epsilon;
+ bool is_within_value = distance(color_hsva.z, key_hsva.z) < value_epsilon;
+ bool is_within_hue = distance(color_hsva.x, key_hsva.x) < hue_epsilon;
+ /* Hue wraps around, so check the distance around the boundary. */
+ float min_hue = min(color_hsva.x, key_hsva.x);
+ float max_hue = max(color_hsva.x, key_hsva.x);
+ is_within_hue = is_within_hue || ((min_hue + (1.0 - max_hue)) < hue_epsilon);
+
+ matte = (is_within_hue && is_within_saturation && is_within_value) ? 0.0 : color.a;
+ result = color * matte;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl
new file mode 100644
index 00000000000..0adad53ad80
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_spill.glsl
@@ -0,0 +1,13 @@
+void node_composite_color_spill(vec4 color,
+ float factor,
+ const float spill_channel,
+ vec3 spill_scale,
+ const vec2 limit_channels,
+ float limit_scale,
+ out vec4 result)
+{
+ float average_limit = (color[int(limit_channels.x)] + color[int(limit_channels.y)]) / 2.0;
+ float map = factor * color[int(spill_channel)] - limit_scale * average_limit;
+ result.rgb = map > 0.0 ? color.rgb + spill_scale * map : color.rgb;
+ result.a = color.a;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl
new file mode 100644
index 00000000000..d769cadce3c
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_difference_matte.glsl
@@ -0,0 +1,10 @@
+void node_composite_difference_matte(
+ vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte)
+{
+ vec4 difference = abs(color - key);
+ float average_difference = (difference.r + difference.g + difference.b) / 3.0;
+ bool is_opaque = average_difference > tolerance + falloff;
+ float alpha = is_opaque ? color.a : (max(0.0, average_difference - tolerance) / falloff);
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl
new file mode 100644
index 00000000000..9beed66826c
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_distance_matte.glsl
@@ -0,0 +1,26 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_distance_matte_rgba(
+ vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte)
+{
+ float difference = distance(color.rgb, key.rgb);
+ bool is_opaque = difference > tolerance + falloff;
+ float alpha = is_opaque ? color.a : max(0.0, difference - tolerance) / falloff;
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
+
+void node_composite_distance_matte_ycca(
+ vec4 color, vec4 key, float tolerance, float falloff, out vec4 result, out float matte)
+{
+ vec4 color_ycca;
+ rgba_to_ycca_itu_709(color, color_ycca);
+ vec4 key_ycca;
+ rgba_to_ycca_itu_709(key, key_ycca);
+
+ float difference = distance(color_ycca.yz, key_ycca.yz);
+ bool is_opaque = difference > tolerance + falloff;
+ float alpha = is_opaque ? color.a : max(0.0, difference - tolerance) / falloff;
+ matte = min(alpha, color.a);
+ result = color * matte;
+}
diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl
new file mode 100644
index 00000000000..3647ac583fe
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_luminance_matte.glsl
@@ -0,0 +1,14 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_luminance_matte(vec4 color,
+ float high,
+ float low,
+ const vec3 luminance_coefficients,
+ out vec4 result,
+ out float matte)
+{
+ float luminance = get_luminance(color.rgb, luminance_coefficients);
+ float alpha = clamp(0.0, 1.0, (luminance - low) / (high - low));
+ matte = min(alpha, color.a);
+ result = color * matte;
+}