[Bf-blender-cvs] [507a331f018] blender-v2.82-release: Fix T67552 EEVEE: Vector Curves node clamps maximum input value at 1.0

Clément Foucault noreply at git.blender.org
Mon Jan 27 19:52:51 CET 2020


Commit: 507a331f0182dd5458e823f705de644613a890b2
Author: Clément Foucault
Date:   Mon Jan 27 19:48:31 2020 +0100
Branches: blender-v2.82-release
https://developer.blender.org/rB507a331f0182dd5458e823f705de644613a890b2

Fix T67552 EEVEE: Vector Curves node clamps maximum input value at 1.0

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

M	source/blender/gpu/shaders/material/gpu_shader_material_vector_curves.glsl
M	source/blender/nodes/shader/nodes/node_shader_curves.c

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

diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_vector_curves.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_vector_curves.glsl
index 35d2e903cf4..63e97e66c90 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_vector_curves.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_vector_curves.glsl
@@ -1,8 +1,41 @@
-void curves_vec(float fac, vec3 vec, sampler1DArray curvemap, float layer, out vec3 outvec)
+/* ext is vec4(in_x, in_dy, out_x, out_dy). */
+float curve_extrapolate(float x, float y, vec4 ext)
 {
-  vec4 co = vec4(vec * 0.5 + 0.5, layer);
+  if (x < 0.0) {
+    return y + x * ext.y;
+  }
+  else if (x > 1.0) {
+    return y + (x - 1.0) * ext.w;
+  }
+  else {
+    return y;
+  }
+}
+
+#define RANGE_RESCALE(x, min, range) ((x - min) * range)
+
+void curves_vec(float fac,
+                vec3 vec,
+                sampler1DArray curvemap,
+                float layer,
+                vec3 range,
+                vec4 ext_x,
+                vec4 ext_y,
+                vec4 ext_z,
+                out vec3 outvec)
+{
+  vec4 co = vec4(vec, layer);
+
+  vec3 xyz_min = vec3(ext_x.x, ext_y.x, ext_z.x);
+  co.xyz = RANGE_RESCALE(co.xyz, xyz_min, range);
+
   outvec.x = texture(curvemap, co.xw).x;
   outvec.y = texture(curvemap, co.yw).y;
   outvec.z = texture(curvemap, co.zw).z;
+
+  outvec.x = curve_extrapolate(co.x, outvec.r, ext_x);
+  outvec.y = curve_extrapolate(co.y, outvec.g, ext_y);
+  outvec.z = curve_extrapolate(co.z, outvec.b, ext_z);
+
   outvec = mix(vec, outvec, fac);
 }
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index 6292d7b5062..d20b919a7fb 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -64,10 +64,44 @@ static int gpu_shader_curve_vec(GPUMaterial *mat,
   float *array, layer;
   int size;
 
-  BKE_curvemapping_table_RGBA(node->storage, &array, &size);
+  CurveMapping *cumap = node->storage;
+
+  BKE_curvemapping_table_RGBA(cumap, &array, &size);
   GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer);
 
-  return GPU_stack_link(mat, node, "curves_vec", in, out, tex, GPU_constant(&layer));
+  float ext_xyz[3][4];
+  float range_xyz[3];
+
+  for (int a = 0; a < 3; a++) {
+    const CurveMap *cm = &cumap->cm[a];
+    ext_xyz[a][0] = cm->mintable;
+    ext_xyz[a][2] = cm->maxtable;
+    range_xyz[a] = 1.0f / max_ff(1e-8f, cm->maxtable - cm->mintable);
+    /* Compute extrapolation gradients. */
+    if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
+      ext_xyz[a][1] = (cm->ext_in[0] != 0.0f) ? (cm->ext_in[1] / (cm->ext_in[0] * range_xyz[a])) :
+                                                1e8f;
+      ext_xyz[a][3] = (cm->ext_out[0] != 0.0f) ?
+                          (cm->ext_out[1] / (cm->ext_out[0] * range_xyz[a])) :
+                          1e8f;
+    }
+    else {
+      ext_xyz[a][1] = 0.0f;
+      ext_xyz[a][3] = 0.0f;
+    }
+  }
+
+  return GPU_stack_link(mat,
+                        node,
+                        "curves_vec",
+                        in,
+                        out,
+                        tex,
+                        GPU_constant(&layer),
+                        GPU_uniform(range_xyz),
+                        GPU_uniform(ext_xyz[0]),
+                        GPU_uniform(ext_xyz[1]),
+                        GPU_uniform(ext_xyz[2]));
 }
 
 void register_node_type_sh_curve_vec(void)



More information about the Bf-blender-cvs mailing list