[Bf-blender-cvs] [506ad72c66d] viewport-compositor: Viewport Compositor: Port Color Correction node

Omar Emara noreply at git.blender.org
Tue Dec 28 20:02:43 CET 2021


Commit: 506ad72c66d3c00d3da6906d824977e143f5fb15
Author: Omar Emara
Date:   Wed Nov 3 12:28:35 2021 +0200
Branches: viewport-compositor
https://developer.blender.org/rB506ad72c66d3c00d3da6906d824977e143f5fb15

Viewport Compositor: Port Color Correction node

This patch ports the Color Correction node to the viewport compositor.
The shader is a straightforward port of the compositor code. A function
to return the luminance coefficients from the color management
configuration was added to pass the coefficients to the shader.

===================================================================

M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/intern/gpu_material_library.c
M	source/blender/gpu/shaders/common/gpu_shader_common_color_util.glsl
M	source/blender/gpu/shaders/common/gpu_shader_common_math_util.glsl
A	source/blender/gpu/shaders/composite/gpu_shader_composite_color_correction.glsl
M	source/blender/imbuf/IMB_colormanagement.h
M	source/blender/imbuf/intern/colormanagement_inline.c
M	source/blender/nodes/composite/nodes/node_composite_colorcorrection.cc

===================================================================

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index cdd8fb466ac..2ac3dfa17b9 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -282,6 +282,7 @@ data_to_c_simple(shaders/common/gpu_shader_common_hash.glsl SRC)
 data_to_c_simple(shaders/composite/gpu_shader_composite_alpha_over.glsl SRC)
 data_to_c_simple(shaders/composite/gpu_shader_composite_bright_contrast.glsl SRC)
 data_to_c_simple(shaders/composite/gpu_shader_composite_color_balance.glsl SRC)
+data_to_c_simple(shaders/composite/gpu_shader_composite_color_correction.glsl SRC)
 data_to_c_simple(shaders/composite/gpu_shader_composite_composite.glsl SRC)
 data_to_c_simple(shaders/composite/gpu_shader_composite_image.glsl SRC)
 data_to_c_simple(shaders/composite/gpu_shader_composite_invert.glsl SRC)
diff --git a/source/blender/gpu/intern/gpu_material_library.c b/source/blender/gpu/intern/gpu_material_library.c
index f9cd64801ed..0c8cdef50ce 100644
--- a/source/blender/gpu/intern/gpu_material_library.c
+++ b/source/blender/gpu/intern/gpu_material_library.c
@@ -48,6 +48,7 @@ extern char datatoc_gpu_shader_common_hash_glsl[];
 extern char datatoc_gpu_shader_composite_alpha_over_glsl[];
 extern char datatoc_gpu_shader_composite_bright_contrast_glsl[];
 extern char datatoc_gpu_shader_composite_color_balance_glsl[];
+extern char datatoc_gpu_shader_composite_color_correction_glsl[];
 extern char datatoc_gpu_shader_composite_composite_glsl[];
 extern char datatoc_gpu_shader_composite_image_glsl[];
 extern char datatoc_gpu_shader_composite_invert_glsl[];
@@ -174,6 +175,13 @@ static GPUMaterialLibrary gpu_shader_composite_color_balance_library = {
                      NULL},
 };
 
+static GPUMaterialLibrary gpu_shader_composite_color_correction_library = {
+    .code = datatoc_gpu_shader_composite_color_correction_glsl,
+    .dependencies = {&gpu_shader_common_math_util_library,
+                     &gpu_shader_common_color_util_library,
+                     NULL},
+};
+
 static GPUMaterialLibrary gpu_shader_composite_composite_library = {
     .code = datatoc_gpu_shader_composite_composite_glsl,
     .dependencies = {NULL},
@@ -718,6 +726,7 @@ static GPUMaterialLibrary *gpu_material_libraries[] = {
     &gpu_shader_composite_alpha_over_library,
     &gpu_shader_composite_bright_contrast_library,
     &gpu_shader_composite_color_balance_library,
+    &gpu_shader_composite_color_correction_library,
     &gpu_shader_composite_composite_library,
     &gpu_shader_composite_image_library,
     &gpu_shader_composite_invert_library,
diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_color_util.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_color_util.glsl
index ff39668b914..c2081482042 100644
--- a/source/blender/gpu/shaders/common/gpu_shader_common_color_util.glsl
+++ b/source/blender/gpu/shaders/common/gpu_shader_common_color_util.glsl
@@ -139,3 +139,8 @@ vec3 srgb_to_linear_rgb(vec3 color)
   return vec3(
       srgb_to_linear_rgb(color.r), srgb_to_linear_rgb(color.g), srgb_to_linear_rgb(color.b));
 }
+
+float get_luminance(vec3 color, vec3 luminance_coefficients)
+{
+  return dot(color, luminance_coefficients);
+}
diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_math_util.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_math_util.glsl
index 3c60c566f22..5b4ae8b69fa 100644
--- a/source/blender/gpu/shaders/common/gpu_shader_common_math_util.glsl
+++ b/source/blender/gpu/shaders/common/gpu_shader_common_math_util.glsl
@@ -38,6 +38,17 @@ float compatible_pow(float x, float y)
   return pow(x, y);
 }
 
+/* A version of pow that returns a fallback value if the computation is undefined. From the spec:
+ * The result is undefined if x < 0 or if x = 0 and y is less than or equal 0. */
+float fallback_pow(float x, float y, float fallback)
+{
+  if (x < 0.0 || (x == 0.0 && y <= 0.0)) {
+    return fallback;
+  }
+
+  return pow(x, y);
+}
+
 float wrap(float a, float b, float c)
 {
   float range = b - c;
@@ -113,6 +124,13 @@ void vector_normalize(vec3 normal, out vec3 outnormal)
   outnormal = normalize(normal);
 }
 
+vec3 fallback_pow(vec3 a, float b, vec3 fallback)
+{
+  return vec3(fallback_pow(a.x, b, fallback.x),
+              fallback_pow(a.y, b, fallback.y),
+              fallback_pow(a.z, b, fallback.z));
+}
+
 /* Matirx Math */
 
 mat3 euler_to_mat3(vec3 euler)
diff --git a/source/blender/gpu/shaders/composite/gpu_shader_composite_color_correction.glsl b/source/blender/gpu/shaders/composite/gpu_shader_composite_color_correction.glsl
new file mode 100644
index 00000000000..00beddf6e1b
--- /dev/null
+++ b/source/blender/gpu/shaders/composite/gpu_shader_composite_color_correction.glsl
@@ -0,0 +1,84 @@
+void node_composite_color_correction(vec4 color,
+                                     float mask,
+                                     const vec3 enabled_channels,
+                                     const vec3 luminance_coefficients,
+                                     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,
+                                     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/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 53b0e295385..09ed78ff39d 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -69,6 +69,7 @@ bool IMB_colormanagement_space_name_is_data(const char *name);
 
 BLI_INLINE float IMB_colormanagement_get_luminance(const float rgb[3]);
 BLI_INLINE unsigned char IMB_colormanagement_get_luminance_byte(const unsigned char[3]);
+BLI_INLINE void IMB_colormanagement_get_luminance_coefficients(float rgb[3]);
 BLI_INLINE void IMB_colormanagement_xyz_to_rgb(float rgb[3], const float xyz[3]);
 BLI_INLINE void IMB_colormanagement_rgb_to_xyz(float xyz[3], const float rgb[3]);
 const float *IMB_colormanagement_get_xyz_to_rgb(void);
diff --git a/source/blender/imbuf/intern/colormanagement_inline.c b/source/blender/imbuf/intern/colormanagement_inline.c
index c304ad8d8e5..6025085d1be 100644
--- a/source/blender/imbuf/intern/colormanagement_inline.c
+++ b/source/blender/imbuf/intern/colormanagement_inline.c
@@ -55,6 +55,11 @@ unsigned char IMB_colormanagement_get_luminance_byte(const unsigned char rgb[3])
   return unit_float_to_uchar_clamp(val);
 }
 
+void IMB_colormanagement_get_luminance_coefficients(float rgb[3])
+{
+  return copy_v3_v3(rgb, imbuf_luma_coefficients);
+}
+
 void IMB_colormanagement_xyz_to_rgb(float rgb[3], const float xyz[3])
 {
   mul_v3_m3v3(rgb, imbuf_xyz_to_rgb, xyz);
diff --git a/source/blender/nodes/composite/nodes/node_composite_colorcorrection.cc b/source/blender/nodes/composite/nodes/node_composite_colorcorrection.cc
index 0682c66f1e8..cf168651c21 100644
--- a/source/blender/nodes/composite/nodes/node_composite_colorcorrection.cc
+++ b/sour

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list