[Bf-blender-cvs] [61a3fad7aac] viewport-compositor: Viewport Compositor: Port RGB Curves node

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


Commit: 61a3fad7aac713ff587406023453a15605120a36
Author: Omar Emara
Date:   Sat Nov 6 21:08:59 2021 +0200
Branches: viewport-compositor
https://developer.blender.org/rB61a3fad7aac713ff587406023453a15605120a36

Viewport Compositor: Port RGB Curves node

This patch ports the RGB Curves node to the viewport compositor. The
curves code was mostly rewritten in a common directory to be used by
both the material and compositor nodes. The new code avoids code
duplication by moving common code into BKE curve mapping functions. It
also avoids ambiguous data embedding into gradient vectors and avoids
redundancies. Finally, a film-like implementation was added.

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

M	source/blender/blenkernel/BKE_colortools.h
M	source/blender/blenkernel/intern/colortools.c
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/intern/gpu_material_library.c
A	source/blender/gpu/shaders/common/gpu_shader_common_curves.glsl
M	source/blender/gpu/shaders/composite/gpu_shader_composite_hue_correct.glsl
D	source/blender/gpu/shaders/material/gpu_shader_material_rgb_curves.glsl
D	source/blender/gpu/shaders/material/gpu_shader_material_vector_curves.glsl
M	source/blender/nodes/composite/nodes/node_composite_curves.cc
M	source/blender/nodes/composite/nodes/node_composite_huecorrect.cc
M	source/blender/nodes/shader/nodes/node_shader_curves.cc

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

diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index ec2262d4f60..410a1bacdaf 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -98,6 +98,14 @@ void BKE_curvemapping_evaluate_premulRGBF(const struct CurveMapping *cumap,
                                           const float vecin[3]);
 bool BKE_curvemapping_RGBA_does_something(const struct CurveMapping *cumap);
 void BKE_curvemapping_table_RGBA(const struct CurveMapping *cumap, float **array, int *size);
+void BKE_curvemapping_get_range_minimums(const struct CurveMapping *curve_mapping,
+                                         float minimums[4]);
+void BKE_curvemapping_compute_range_dividers(const struct CurveMapping *curve_mapping,
+                                             float dividers[4]);
+void BKE_curvemapping_compute_slopes(const struct CurveMapping *curve_mapping,
+                                     float start_slopes[4],
+                                     float end_slopes[4]);
+bool BKE_curvemapping_is_map_identity(const struct CurveMapping *curve_mapping, int index);
 
 /* non-const, these modify the curve */
 void BKE_curvemapping_premultiply(struct CurveMapping *cumap, int restore);
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index f2c2e552a9f..a9442c48201 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1197,6 +1197,98 @@ bool BKE_curvemapping_RGBA_does_something(const CurveMapping *cumap)
   return false;
 }
 
+/* Get the minimum x value of each curve map table. */
+void BKE_curvemapping_get_range_minimums(const CurveMapping *curve_mapping, float minimums[CM_TOT])
+{
+  for (int i = 0; i < CM_TOT; i++) {
+    minimums[i] = curve_mapping->cm[i].mintable;
+  }
+}
+
+/* Get the reciprocal of the difference between the maximum and the minimum x value of each curve
+ * map table. Evaluation parameters can be multiplied by this value to be normalized. If the
+ * difference is zero, 1^8 is returned. */
+void BKE_curvemapping_compute_range_dividers(const CurveMapping *curve_mapping,
+                                             float dividers[CM_TOT])
+{
+  for (int i = 0; i < CM_TOT; i++) {
+    const CurveMap *curve_map = &curve_mapping->cm[i];
+    dividers[i] = 1.0f / max_ff(1e-8f, curve_map->maxtable - curve_map->mintable);
+  }
+}
+
+/* Compute the slopes at the start and end points of each curve map. The slopes are multiplied by
+ * the range of the curve map to compensate for parameter normalization. If the slope is vertical,
+ * 1^8 is returned.  */
+void BKE_curvemapping_compute_slopes(const CurveMapping *curve_mapping,
+                                     float start_slopes[CM_TOT],
+                                     float end_slopes[CM_TOT])
+{
+  float range_dividers[CM_TOT];
+  BKE_curvemapping_compute_range_dividers(curve_mapping, range_dividers);
+  for (int i = 0; i < CM_TOT; i++) {
+    const CurveMap *curve_map = &curve_mapping->cm[i];
+    /* If extrapolation is not enabled, the slopes are horizontal. */
+    if (!(curve_mapping->flag & CUMA_EXTEND_EXTRAPOLATE)) {
+      start_slopes[i] = 0.0f;
+      end_slopes[i] = 0.0f;
+      continue;
+    }
+
+    if (curve_map->ext_in[0] != 0.0f) {
+      start_slopes[i] = curve_map->ext_in[1] / (curve_map->ext_in[0] * range_dividers[i]);
+    }
+    else {
+      start_slopes[i] = 1e8f;
+    }
+
+    if (curve_map->ext_out[0] != 0.0f) {
+      end_slopes[i] = curve_map->ext_out[1] / (curve_map->ext_out[0] * range_dividers[i]);
+    }
+    else {
+      end_slopes[i] = 1e8f;
+    }
+  }
+}
+
+/* Check if the curve map at the index is identity, that is, does nothing. A curve map is said to
+ * be identity if:
+ * - The curve mapping uses extrapolation.
+ * - Its range is 1.
+ * - The slope at its start point is 1.
+ * - The slope at its end point is 1.
+ * - The number of points is 2.
+ * - The start point is at (0, 0).
+ * - The end point is at (1, 1).
+ * Note that this could return false even if the curve map is identity, this happens in the case
+ * when more than 2 points exist in the curve map but all points are collinear. */
+bool BKE_curvemapping_is_map_identity(const CurveMapping *curve_mapping, int index)
+{
+  if (!(curve_mapping->flag & CUMA_EXTEND_EXTRAPOLATE)) {
+    return false;
+  }
+  const CurveMap *curve_map = &curve_mapping->cm[index];
+  if (curve_map->maxtable - curve_map->mintable != 1.0f) {
+    return false;
+  }
+  if (curve_map->ext_in[0] != curve_map->ext_in[1]) {
+    return false;
+  }
+  if (curve_map->ext_out[0] != curve_map->ext_out[1]) {
+    return false;
+  }
+  if (curve_map->totpoint != 2) {
+    return false;
+  }
+  if (curve_map->curve[0].x != 0 || curve_map->curve[0].y != 0) {
+    return false;
+  }
+  if (curve_map->curve[1].x != 0 || curve_map->curve[1].y != 0) {
+    return false;
+  }
+  return true;
+}
+
 void BKE_curvemapping_init(CurveMapping *cumap)
 {
   int a;
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 932ceecf464..d5de5722dfe 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -276,6 +276,7 @@ data_to_c_simple(shaders/gpu_shader_codegen_lib.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC)
 
 data_to_c_simple(shaders/common/gpu_shader_common_color_util.glsl SRC)
+data_to_c_simple(shaders/common/gpu_shader_common_curves.glsl SRC)
 data_to_c_simple(shaders/common/gpu_shader_common_math_util.glsl SRC)
 data_to_c_simple(shaders/common/gpu_shader_common_mix_rgb.glsl SRC)
 data_to_c_simple(shaders/common/gpu_shader_common_hash.glsl SRC)
@@ -340,7 +341,6 @@ data_to_c_simple(shaders/material/gpu_shader_material_output_world.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_particle_info.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_principled.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_refraction.glsl SRC)
-data_to_c_simple(shaders/material/gpu_shader_material_rgb_curves.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_rgb_to_bw.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_separate_hsv.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_separate_rgb.glsl SRC)
@@ -367,7 +367,6 @@ data_to_c_simple(shaders/material/gpu_shader_material_toon.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_translucent.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_transparent.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_uv_map.glsl SRC)
-data_to_c_simple(shaders/material/gpu_shader_material_vector_curves.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_vector_displacement.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_vector_math.glsl SRC)
 data_to_c_simple(shaders/material/gpu_shader_material_vector_rotate.glsl SRC)
diff --git a/source/blender/gpu/intern/gpu_material_library.c b/source/blender/gpu/intern/gpu_material_library.c
index 1beb281d79b..38930dd9293 100644
--- a/source/blender/gpu/intern/gpu_material_library.c
+++ b/source/blender/gpu/intern/gpu_material_library.c
@@ -42,6 +42,7 @@
  * dependencies, and be placed after that file in the list. */
 
 extern char datatoc_gpu_shader_common_color_util_glsl[];
+extern char datatoc_gpu_shader_common_curves_glsl[];
 extern char datatoc_gpu_shader_common_math_util_glsl[];
 extern char datatoc_gpu_shader_common_mix_rgb_glsl[];
 extern char datatoc_gpu_shader_common_hash_glsl[];
@@ -106,7 +107,6 @@ extern char datatoc_gpu_shader_material_output_world_glsl[];
 extern char datatoc_gpu_shader_material_particle_info_glsl[];
 extern char datatoc_gpu_shader_material_principled_glsl[];
 extern char datatoc_gpu_shader_material_refraction_glsl[];
-extern char datatoc_gpu_shader_material_rgb_curves_glsl[];
 extern char datatoc_gpu_shader_material_rgb_to_bw_glsl[];
 extern char datatoc_gpu_shader_material_separate_hsv_glsl[];
 extern char datatoc_gpu_shader_material_separate_rgb_glsl[];
@@ -133,7 +133,6 @@ extern char datatoc_gpu_shader_material_toon_glsl[];
 extern char datatoc_gpu_shader_material_translucent_glsl[];
 extern char datatoc_gpu_shader_material_transparent_glsl[];
 extern char datatoc_gpu_shader_material_uv_map_glsl[];
-extern char datatoc_gpu_shader_material_vector_curves_glsl[];
 extern char datatoc_gpu_shader_material_vector_displacement_glsl[];
 extern char datatoc_gpu_shader_material_vector_math_glsl[];
 extern char datatoc_gpu_shader_material_vector_rotate_glsl[];
@@ -156,6 +155,11 @@ static GPUMaterialLibrary gpu_shader_common_color_util_library = {
     .dependencies = {NULL},
 };
 
+static GPUMaterialLibrary gpu_shader_common_curves_library = {
+    .code = datatoc_gpu_shader_common_curves_glsl,
+    .dependencies = {NULL},
+};
+
 static GPUMaterialLibrary gpu_shader_common_mix_rgb_library = {
     .code = datatoc_gpu_shader_common_mix_rgb_glsl,
     .dependencies = {&gpu_shader_common_color_util_library, NULL},
@@ -472,11 +476,6 @@ static GPUMaterialLibrary gpu_shader_material_refraction_library = {
     .dependencies = {NULL},
 };
 
-static GPUMaterialLibrary gpu_shader_material_rgb_curves_library = {
-    .code = datatoc_gpu_shader_material_rgb_curves_glsl,
-    .dependencies = {NULL},
-};
-
 static GPUMaterialLibrary gpu_shader_material_rgb_to_bw_library = {
     .code = datatoc_gpu_shader_material_rgb_to_bw_glsl,
     .dependencies = {NULL},
@@ -602,11 +601,6 @@ static GPUMaterialLibrary gpu_shader_material_uv_map_library = {
     .dependencies = {NULL},
 };
 
-static GPUMaterialLibrary gpu_shader_material_vector_curves_library = {
-    .code = datatoc_gpu_shader_material_vector_curves_glsl,
-    .dependencies = {NULL},
-};
-
 static GPUMaterialLibrary gpu_shader_material_vector_displacement_library = {
     .code = datatoc_gpu_shader_material_vector_displacement_glsl,
     .dependencies = {NULL},
@@ -665,6 +659,7 @@ static GPUMaterialLibrary gpu_shader_material_world_normals_library = {
 static GPUMaterialLibrary *gpu_material_libraries[] = {
     &gpu_shader_common_math_util_library,
     &gpu_shader_co

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list