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/compositor/realtime_compositor/shaders/library')
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl48
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl32
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl38
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl52
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl43
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl34
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl87
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl27
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl6
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl10
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl26
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl6
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl7
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl39
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl16
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl13
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl14
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl7
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl56
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl9
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl6
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl132
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl9
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl26
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl35
-rw-r--r--source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl29
27 files changed, 820 insertions, 0 deletions
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl
new file mode 100644
index 00000000000..8e3e033147f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_alpha_over.glsl
@@ -0,0 +1,48 @@
+void node_composite_alpha_over_mixed(
+ float factor, vec4 color, vec4 over_color, float premultiply_factor, out vec4 result)
+{
+ if (over_color.a <= 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ float add_factor = 1.0 - premultiply_factor + over_color.a * premultiply_factor;
+ float premultiplier = factor * add_factor;
+ float multiplier = 1.0 - factor * over_color.a;
+
+ result = multiplier * color + vec2(premultiplier, factor).xxxy * over_color;
+ }
+}
+
+void node_composite_alpha_over_key(float factor, vec4 color, vec4 over_color, out vec4 result)
+{
+ if (over_color.a <= 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ result = mix(color, vec4(over_color.rgb, 1.0), factor * over_color.a);
+ }
+}
+
+void node_composite_alpha_over_premultiply(float factor,
+ vec4 color,
+ vec4 over_color,
+ out vec4 result)
+{
+ if (over_color.a < 0.0) {
+ result = color;
+ }
+ else if (factor == 1.0 && over_color.a >= 1.0) {
+ result = over_color;
+ }
+ else {
+ float multiplier = 1.0 - factor * over_color.a;
+
+ result = multiplier * color + factor * over_color;
+ }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_blur_common.glsl
new file mode 100644
index 00000000000..e404c03bbb0
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/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;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl
new file mode 100644
index 00000000000..ce71b4fd8a4
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_bright_contrast.glsl
@@ -0,0 +1,38 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* The algorithm is by Werner D. Streidt
+ * (http://visca.com/ffactory/archives/5-99/msg00021.html)
+ * Extracted of OpenCV demhist.c
+ */
+
+#define FLT_EPSILON 1.192092896e-07F
+
+void node_composite_bright_contrast(
+ vec4 color, float brightness, float contrast, const float use_premultiply, out vec4 result)
+{
+ brightness /= 100.0;
+ float delta = contrast / 200.0;
+
+ float multiplier, offset;
+ if (contrast > 0.0) {
+ multiplier = 1.0 - delta * 2.0;
+ multiplier = 1.0 / max(multiplier, FLT_EPSILON);
+ offset = multiplier * (brightness - delta);
+ }
+ else {
+ delta *= -1.0;
+ multiplier = max(1.0 - delta * 2.0, 0.0);
+ offset = multiplier * brightness + delta;
+ }
+
+ if (use_premultiply != 0.0) {
+ color_alpha_unpremultiply(color, color);
+ }
+
+ result.rgb = color.rgb * multiplier + offset;
+ result.a = color.a;
+
+ if (use_premultiply != 0.0) {
+ color_alpha_premultiply(result, result);
+ }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_channel_matte.glsl
new file mode 100644
index 00000000000..f2dcc9543f2
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/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/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_chroma_matte.glsl
new file mode 100644
index 00000000000..5d6bea0c9db
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/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/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl
new file mode 100644
index 00000000000..bffb94cdedb
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_balance.glsl
@@ -0,0 +1,34 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_color_balance_lgg(
+ float factor, vec4 color, vec3 lift, vec3 gamma, vec3 gain, out vec4 result)
+{
+ lift = 2.0 - lift;
+ vec3 srgb_color = linear_rgb_to_srgb(color.rgb);
+ vec3 lift_balanced = ((srgb_color - 1.0) * lift) + 1.0;
+
+ vec3 gain_balanced = lift_balanced * gain;
+ gain_balanced = max(gain_balanced, vec3(0.0));
+
+ vec3 linear_color = srgb_to_linear_rgb(gain_balanced);
+ gamma = mix(gamma, vec3(1e-6), equal(gamma, vec3(0.0)));
+ vec3 gamma_balanced = pow(linear_color, 1.0 / gamma);
+
+ result.rgb = mix(color.rgb, gamma_balanced, min(factor, 1.0));
+ result.a = color.a;
+}
+
+void node_composite_color_balance_asc_cdl(float factor,
+ vec4 color,
+ vec3 offset,
+ vec3 power,
+ vec3 slope,
+ float offset_basis,
+ out vec4 result)
+{
+ offset += offset_basis;
+ vec3 balanced = color.rgb * slope + offset;
+ balanced = pow(max(balanced, vec3(0.0)), power);
+ result.rgb = mix(color.rgb, balanced, min(factor, 1.0));
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl
new file mode 100644
index 00000000000..9b4858f03be
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_correction.glsl
@@ -0,0 +1,87 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_color_correction(vec4 color,
+ float mask,
+ const vec3 enabled_channels,
+ float start_midtones,
+ float end_midtones,
+ float master_saturation,
+ float master_contrast,
+ float master_gamma,
+ float master_gain,
+ float master_lift,
+ float shadows_saturation,
+ float shadows_contrast,
+ float shadows_gamma,
+ float shadows_gain,
+ float shadows_lift,
+ float midtones_saturation,
+ float midtones_contrast,
+ float midtones_gamma,
+ float midtones_gain,
+ float midtones_lift,
+ float highlights_saturation,
+ float highlights_contrast,
+ float highlights_gamma,
+ float highlights_gain,
+ float highlights_lift,
+ const vec3 luminance_coefficients,
+ out vec4 result)
+{
+ const float margin = 0.10;
+ const float margin_divider = 0.5 / margin;
+ float level = (color.r + color.g + color.b) / 3.0;
+ float level_shadows = 0.0;
+ float level_midtones = 0.0;
+ float level_highlights = 0.0;
+ if (level < (start_midtones - margin)) {
+ level_shadows = 1.0;
+ }
+ else if (level < (start_midtones + margin)) {
+ level_midtones = ((level - start_midtones) * margin_divider) + 0.5;
+ level_shadows = 1.0 - level_midtones;
+ }
+ else if (level < (end_midtones - margin)) {
+ level_midtones = 1.0;
+ }
+ else if (level < (end_midtones + margin)) {
+ level_highlights = ((level - end_midtones) * margin_divider) + 0.5;
+ level_midtones = 1.0 - level_highlights;
+ }
+ else {
+ level_highlights = 1.0;
+ }
+
+ float contrast = level_shadows * shadows_contrast;
+ contrast += level_midtones * midtones_contrast;
+ contrast += level_highlights * highlights_contrast;
+ contrast *= master_contrast;
+ float saturation = level_shadows * shadows_saturation;
+ saturation += level_midtones * midtones_saturation;
+ saturation += level_highlights * highlights_saturation;
+ saturation *= master_saturation;
+ float gamma = level_shadows * shadows_gamma;
+ gamma += level_midtones * midtones_gamma;
+ gamma += level_highlights * highlights_gamma;
+ gamma *= master_gamma;
+ float gain = level_shadows * shadows_gain;
+ gain += level_midtones * midtones_gain;
+ gain += level_highlights * highlights_gain;
+ gain *= master_gain;
+ float lift = level_shadows * shadows_lift;
+ lift += level_midtones * midtones_lift;
+ lift += level_highlights * highlights_lift;
+ lift += master_lift;
+
+ float inverse_gamma = 1.0 / gamma;
+ float luma = get_luminance(color.rgb, luminance_coefficients);
+
+ vec3 corrected = luma + saturation * (color.rgb - luma);
+ corrected = 0.5 + (corrected - 0.5) * contrast;
+ corrected = fallback_pow(corrected * gain + lift, inverse_gamma, corrected);
+ corrected = mix(color.rgb, corrected, min(mask, 1.0));
+
+ result.rgb = mix(corrected, color.rgb, equal(enabled_channels, vec3(0.0)));
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_matte.glsl
new file mode 100644
index 00000000000..038471bc1bc
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/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/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_spill.glsl
new file mode 100644
index 00000000000..0adad53ad80
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/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/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl
new file mode 100644
index 00000000000..bcdd625bd4f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_color_to_luminance.glsl
@@ -0,0 +1,6 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void color_to_luminance(vec4 color, const vec3 luminance_coefficients, out float result)
+{
+ result = get_luminance(color.rgb, luminance_coefficients);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_difference_matte.glsl
new file mode 100644
index 00000000000..d769cadce3c
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/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/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_distance_matte.glsl
new file mode 100644
index 00000000000..9beed66826c
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/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/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl
new file mode 100644
index 00000000000..f246635a91e
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_exposure.glsl
@@ -0,0 +1,6 @@
+void node_composite_exposure(vec4 color, float exposure, out vec4 result)
+{
+ float multiplier = exp2(exposure);
+ result.rgb = color.rgb * multiplier;
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl
new file mode 100644
index 00000000000..53070d4b0e2
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_gamma.glsl
@@ -0,0 +1,7 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl)
+
+void node_composite_gamma(vec4 color, float gamma, out vec4 result)
+{
+ result.rgb = fallback_pow(color.rgb, gamma, color.rgb);
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl
new file mode 100644
index 00000000000..99eb125cdf2
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_correct.glsl
@@ -0,0 +1,39 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* Curve maps are stored in sampler objects that are evaluated in the [0, 1] range, so normalize
+ * parameters accordingly. */
+#define NORMALIZE_PARAMETER(parameter, minimum, range) ((parameter - minimum) * range)
+
+void node_composite_hue_correct(float factor,
+ vec4 color,
+ sampler1DArray curve_map,
+ const float layer,
+ vec3 minimums,
+ vec3 range_dividers,
+ out vec4 result)
+{
+ vec4 hsv;
+ rgb_to_hsv(color, hsv);
+
+ /* First, adjust the hue channel on its own, since corrections in the saturation and value
+ * channels depends on the new value of the hue, not its original value. A curve map value of 0.5
+ * means no change in hue, so adjust the value to get an identity at 0.5. Since the identity of
+ * addition is 0, we subtract 0.5 (0.5 - 0.5 = 0). */
+ const float hue_parameter = NORMALIZE_PARAMETER(hsv.x, minimums.x, range_dividers.x);
+ hsv.x += texture(curve_map, vec2(hue_parameter, layer)).x - 0.5;
+
+ /* Second, adjust the saturation and value based on the new value of the hue. A curve map value
+ * of 0.5 means no change in hue, so adjust the value to get an identity at 0.5. Since the
+ * identity of duplication is 1, we multiply by 2 (0.5 * 2 = 1). */
+ vec2 parameters = NORMALIZE_PARAMETER(hsv.x, minimums.yz, range_dividers.yz);
+ hsv.y *= texture(curve_map, vec2(parameters.x, layer)).y * 2.0;
+ hsv.z *= texture(curve_map, vec2(parameters.y, layer)).z * 2.0;
+
+ /* Sanitize the new hue and saturation values. */
+ hsv.x = fract(hsv.x);
+ hsv.y = clamp(hsv.y, 0.0, 1.0);
+
+ hsv_to_rgb(hsv, result);
+
+ result = mix(color, result, factor);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl
new file mode 100644
index 00000000000..dd5eb33d318
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_hue_saturation_value.glsl
@@ -0,0 +1,16 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_hue_saturation_value(
+ vec4 color, float hue, float saturation, float value, float factor, out vec4 result)
+{
+ vec4 hsv;
+ rgb_to_hsv(color, hsv);
+
+ hsv.x = fract(hsv.x + hue + 0.5);
+ hsv.y = clamp(hsv.y * saturation, 0.0, 1.0);
+ hsv.z = hsv.z * value;
+
+ hsv_to_rgb(hsv, result);
+
+ result = mix(color, result, factor);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl
new file mode 100644
index 00000000000..59be746da7f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_invert.glsl
@@ -0,0 +1,13 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+void node_composite_invert(float fac, vec4 color, float do_rgb, float do_alpha, out vec4 result)
+{
+ result = color;
+ if (do_rgb != 0.0) {
+ result.rgb = 1.0 - result.rgb;
+ }
+ if (do_alpha != 0.0) {
+ result.a = 1.0 - result.a;
+ }
+ result = mix(color, result, fac);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_luminance_matte.glsl
new file mode 100644
index 00000000000..3647ac583fe
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/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;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl
new file mode 100644
index 00000000000..27624223dbc
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_main.glsl
@@ -0,0 +1,7 @@
+/* The compute shader that will be dispatched by the compositor ShaderOperation. It just calls the
+ * evaluate function that will be dynamically generated and appended to this shader in the
+ * ShaderOperation::generate_code method. */
+void main()
+{
+ evaluate();
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl
new file mode 100644
index 00000000000..20874b4ef44
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_map_value.glsl
@@ -0,0 +1,56 @@
+/* An arbitrary value determined by Blender. */
+#define BLENDER_ZMAX 10000.0
+
+void node_composite_map_range(float value,
+ float from_min,
+ float from_max,
+ float to_min,
+ float to_max,
+ const float should_clamp,
+ out float result)
+{
+ if (abs(from_max - from_min) < 1e-6) {
+ result = 0.0;
+ }
+ else {
+ if (value >= -BLENDER_ZMAX && value <= BLENDER_ZMAX) {
+ result = (value - from_min) / (from_max - from_min);
+ result = to_min + result * (to_max - to_min);
+ }
+ else if (value > BLENDER_ZMAX) {
+ result = to_max;
+ }
+ else {
+ result = to_min;
+ }
+
+ if (should_clamp != 0.0) {
+ if (to_max > to_min) {
+ result = clamp(result, to_min, to_max);
+ }
+ else {
+ result = clamp(result, to_max, to_min);
+ }
+ }
+ }
+}
+
+void node_composite_map_value(float value,
+ float offset,
+ float size,
+ const float use_min,
+ float min,
+ const float use_max,
+ float max,
+ out float result)
+{
+ result = (value + offset) * size;
+
+ if (use_min != 0.0 && result < min) {
+ result = min;
+ }
+
+ if (use_max != 0.0 && result > max) {
+ result = max;
+ }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl
new file mode 100644
index 00000000000..a2e3b6c4aaa
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_normal.glsl
@@ -0,0 +1,9 @@
+void node_composite_normal(vec3 input_vector,
+ vec3 input_normal,
+ out vec3 result_normal,
+ out float result_dot)
+{
+ vec3 normal = normalize(input_normal);
+ result_normal = normal;
+ result_dot = -dot(input_vector, normal);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl
new file mode 100644
index 00000000000..ee8ae234abe
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_posterize.glsl
@@ -0,0 +1,6 @@
+void node_composite_posterize(vec4 color, float steps, out vec4 result)
+{
+ steps = clamp(steps, 2.0, 1024.0);
+ result = floor(color * steps) / steps;
+ result.a = color.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl
new file mode 100644
index 00000000000..d72d2260394
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_separate_combine.glsl
@@ -0,0 +1,132 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
+
+/* ** Combine/Separate XYZ ** */
+
+void node_composite_combine_xyz(float x, float y, float z, out vec3 vector)
+{
+ vector = vec3(x, y, z);
+}
+
+void node_composite_separate_xyz(vec3 vector, out float x, out float y, out float z)
+{
+ x = vector.x;
+ y = vector.y;
+ z = vector.z;
+}
+
+/* ** Combine/Separate RGBA ** */
+
+void node_composite_combine_rgba(float r, float g, float b, float a, out vec4 color)
+{
+ color = vec4(r, g, b, a);
+}
+
+void node_composite_separate_rgba(vec4 color, out float r, out float g, out float b, out float a)
+{
+ r = color.r;
+ g = color.g;
+ b = color.b;
+ a = color.a;
+}
+
+/* ** Combine/Separate HSVA ** */
+
+void node_composite_combine_hsva(float h, float s, float v, float a, out vec4 color)
+{
+ hsv_to_rgb(vec4(h, s, v, a), color);
+}
+
+void node_composite_separate_hsva(vec4 color, out float h, out float s, out float v, out float a)
+{
+ vec4 hsva;
+ rgb_to_hsv(color, hsva);
+ h = hsva.x;
+ s = hsva.y;
+ v = hsva.z;
+ a = hsva.a;
+}
+
+/* ** Combine/Separate HSLA ** */
+
+void node_composite_combine_hsla(float h, float s, float l, float a, out vec4 color)
+{
+ hsl_to_rgb(vec4(h, s, l, a), color);
+}
+
+void node_composite_separate_hsla(vec4 color, out float h, out float s, out float l, out float a)
+{
+ vec4 hsla;
+ rgb_to_hsl(color, hsla);
+ h = hsla.x;
+ s = hsla.y;
+ l = hsla.z;
+ a = hsla.a;
+}
+
+/* ** Combine/Separate YCCA ** */
+
+void node_composite_combine_ycca_itu_601(float y, float cb, float cr, float a, out vec4 color)
+{
+ ycca_to_rgba_itu_601(vec4(y, cb, cr, a), color);
+}
+
+void node_composite_combine_ycca_itu_709(float y, float cb, float cr, float a, out vec4 color)
+{
+ ycca_to_rgba_itu_709(vec4(y, cb, cr, a), color);
+}
+
+void node_composite_combine_ycca_jpeg(float y, float cb, float cr, float a, out vec4 color)
+{
+ ycca_to_rgba_jpeg(vec4(y, cb, cr, a), color);
+}
+
+void node_composite_separate_ycca_itu_601(
+ vec4 color, out float y, out float cb, out float cr, out float a)
+{
+ vec4 ycca;
+ rgba_to_ycca_itu_601(color, ycca);
+ y = ycca.x;
+ cb = ycca.y;
+ cr = ycca.z;
+ a = ycca.a;
+}
+
+void node_composite_separate_ycca_itu_709(
+ vec4 color, out float y, out float cb, out float cr, out float a)
+{
+ vec4 ycca;
+ rgba_to_ycca_itu_709(color, ycca);
+ y = ycca.x;
+ cb = ycca.y;
+ cr = ycca.z;
+ a = ycca.a;
+}
+
+void node_composite_separate_ycca_jpeg(
+ vec4 color, out float y, out float cb, out float cr, out float a)
+{
+ vec4 ycca;
+ rgba_to_ycca_jpeg(color, ycca);
+ y = ycca.x;
+ cb = ycca.y;
+ cr = ycca.z;
+ a = ycca.a;
+}
+
+/* ** Combine/Separate YUVA ** */
+
+void node_composite_combine_yuva_itu_709(float y, float u, float v, float a, out vec4 color)
+{
+ yuva_to_rgba_itu_709(vec4(y, u, v, a), color);
+}
+
+void node_composite_separate_yuva_itu_709(
+ vec4 color, out float y, out float u, out float v, out float a)
+{
+ vec4 yuva;
+ rgba_to_yuva_itu_709(color, yuva);
+ y = yuva.x;
+ u = yuva.y;
+ v = yuva.z;
+ a = yuva.a;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl
new file mode 100644
index 00000000000..95380d1ed0f
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_set_alpha.glsl
@@ -0,0 +1,9 @@
+void node_composite_set_alpha_apply(vec4 color, float alpha, out vec4 result)
+{
+ result = color * alpha;
+}
+
+void node_composite_set_alpha_replace(vec4 color, float alpha, out vec4 result)
+{
+ result = vec4(color.rgb, alpha);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl
new file mode 100644
index 00000000000..7fba26907b5
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_store_output.glsl
@@ -0,0 +1,26 @@
+/* The following functions are called to store the given value in the output identified by the
+ * given ID. The ID is an unsigned integer that is encoded in a float, so floatBitsToUint is called
+ * to get the actual identifier. The functions have an output value as their last argument that is
+ * used to establish an output link that is then used to track the nodes that contribute to the
+ * output of the compositor node tree.
+ *
+ * The store_[float|vector|color] functions are dynamically generated in
+ * ShaderOperation::generate_code_for_outputs. */
+
+void node_compositor_store_output_float(const float id, float value, out float out_value)
+{
+ store_float(floatBitsToUint(id), value);
+ out_value = value;
+}
+
+void node_compositor_store_output_vector(const float id, vec3 vector, out vec3 out_vector)
+{
+ store_vector(floatBitsToUint(id), vector);
+ out_vector = vector;
+}
+
+void node_compositor_store_output_color(const float id, vec4 color, out vec4 out_color)
+{
+ store_color(floatBitsToUint(id), color);
+ out_color = color;
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl
new file mode 100644
index 00000000000..128fc6aeaf5
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl
@@ -0,0 +1,35 @@
+/* A shorthand for 1D textureSize with a zero LOD. */
+int texture_size(sampler1D sampler)
+{
+ return textureSize(sampler, 0);
+}
+
+/* A shorthand for 1D texelFetch with zero LOD and bounded access clamped to border. */
+vec4 texture_load(sampler1D sampler, int x)
+{
+ const int texture_bound = texture_size(sampler) - 1;
+ return texelFetch(sampler, clamp(x, 0, texture_bound), 0);
+}
+
+/* A shorthand for 2D textureSize with a zero LOD. */
+ivec2 texture_size(sampler2D sampler)
+{
+ return textureSize(sampler, 0);
+}
+
+/* A shorthand for 2D texelFetch with zero LOD and bounded access clamped to border. */
+vec4 texture_load(sampler2D sampler, ivec2 texel)
+{
+ const ivec2 texture_bounds = texture_size(sampler) - ivec2(1);
+ return texelFetch(sampler, clamp(texel, ivec2(0), texture_bounds), 0);
+}
+
+/* A shorthand for 2D texelFetch with zero LOD and a fallback value for out-of-bound access. */
+vec4 texture_load(sampler2D sampler, ivec2 texel, vec4 fallback)
+{
+ const ivec2 texture_bounds = texture_size(sampler) - ivec2(1);
+ if (any(lessThan(texel, ivec2(0))) || any(greaterThan(texel, texture_bounds))) {
+ return fallback;
+ }
+ return texelFetch(sampler, texel, 0);
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl
new file mode 100644
index 00000000000..75c76fd7341
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_type_conversion.glsl
@@ -0,0 +1,29 @@
+float float_from_vec4(vec4 vector)
+{
+ return dot(vector.rgb, vec3(1.0)) / 3.0;
+}
+
+float float_from_vec3(vec3 vector)
+{
+ return dot(vector, vec3(1.0)) / 3.0;
+}
+
+vec3 vec3_from_vec4(vec4 vector)
+{
+ return vector.rgb;
+}
+
+vec3 vec3_from_float(float value)
+{
+ return vec3(value);
+}
+
+vec4 vec4_from_vec3(vec3 vector)
+{
+ return vec4(vector, 1.0);
+}
+
+vec4 vec4_from_float(float value)
+{
+ return vec4(vec3(value), 1.0);
+}