[Bf-blender-cvs] [e1a62fa1a61] master: Fix T62259: RGB Curves behave differently in Cycles and Eevee

Clément Foucault noreply at git.blender.org
Thu Mar 7 01:38:10 CET 2019


Commit: e1a62fa1a61167990c4ade74b9e8b56573e18d2d
Author: Clément Foucault
Date:   Wed Mar 6 23:53:35 2019 +0100
Branches: master
https://developer.blender.org/rBe1a62fa1a61167990c4ade74b9e8b56573e18d2d

Fix T62259: RGB Curves behave differently in Cycles and Eevee

This was due to curve being not extrapolated correctly. Also curvemap range
was not taken into account.

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

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

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

diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index a7231bda263..422487d075d 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -479,16 +479,49 @@ void curves_vec(float fac, vec3 vec, sampler1DArray curvemap, float layer, out v
 	outvec = mix(vec, outvec, fac);
 }
 
-void curves_rgb(float fac, vec4 col, sampler1DArray curvemap, float layer, out vec4 outcol)
-{
-	vec4 co = vec4(col.rgb, layer);
-	co.x = texture(curvemap, co.xw).a;
-	co.y = texture(curvemap, co.yw).a;
-	co.z = texture(curvemap, co.zw).a;
-	outcol.r = texture(curvemap, co.xw).r;
-	outcol.g = texture(curvemap, co.yw).g;
-	outcol.b = texture(curvemap, co.zw).b;
+/* ext is vec4(in_x, in_dy, out_x, out_dy). */
+float curve_extrapolate(float x, float y, vec4 ext)
+{
+	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_rgb(
+        float fac, vec4 col, sampler1DArray curvemap, float layer,
+        vec4 range, vec4 ext_r, vec4 ext_g, vec4 ext_b, vec4 ext_a,
+        out vec4 outcol)
+{
+	vec4 co = vec4(RANGE_RESCALE(col.rgb, ext_a.x, range.a), layer);
+	vec3 samp;
+	samp.r = texture(curvemap, co.xw).a;
+	samp.g = texture(curvemap, co.yw).a;
+	samp.b = texture(curvemap, co.zw).a;
+
+	samp.r = curve_extrapolate(co.x, samp.r, ext_a);
+	samp.g = curve_extrapolate(co.y, samp.g, ext_a);
+	samp.b = curve_extrapolate(co.z, samp.b, ext_a);
+
+	vec3 rgb_min = vec3(ext_r.x, ext_g.x, ext_b.x);
+	co.xyz = RANGE_RESCALE(samp.rgb, rgb_min, range.rgb);
+
+	samp.r = texture(curvemap, co.xw).r;
+	samp.g = texture(curvemap, co.yw).g;
+	samp.b = texture(curvemap, co.zw).b;
+
+	outcol.r = curve_extrapolate(co.x, samp.r, ext_r);
+	outcol.g = curve_extrapolate(co.y, samp.g, ext_g);
+	outcol.b = curve_extrapolate(co.z, samp.b, ext_b);
 	outcol.a = col.a;
+
 	outcol = mix(col, outcol, fac);
 }
 
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index 4b89f8d26f8..e4c37636347 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -116,11 +116,39 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat, bNode *node, bNodeExecData *UN
 	float *array, layer;
 	int size;
 
-	curvemapping_initialize(node->storage);
-	curvemapping_table_RGBA(node->storage, &array, &size);
+	CurveMapping *cumap = node->storage;
+
+	curvemapping_initialize(cumap);
+	curvemapping_table_RGBA(cumap, &array, &size);
 	GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer);
 
-	return GPU_stack_link(mat, node, "curves_rgb", in, out, tex, GPU_constant(&layer));
+	float ext_rgba[4][4];
+	float range_rgba[4];
+
+	for (int a = 0; a < CM_TOT; ++a) {
+		const CurveMap *cm = &cumap->cm[a];
+		ext_rgba[a][0] = cm->mintable;
+		ext_rgba[a][2] = cm->maxtable;
+		range_rgba[a] = 1.0f / max_ff(1e-8f, cm->maxtable - cm->mintable);
+		/* Compute extrapolation gradients. */
+		if ((cm->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
+			ext_rgba[a][1] = (cm->ext_in[0] != 0.0f) ? (cm->ext_in[1] / (cm->ext_in[0] * range_rgba[a])) : 1e8f;
+			ext_rgba[a][3] = (cm->ext_out[0] != 0.0f) ? (cm->ext_out[1] / (cm->ext_out[0] * range_rgba[a])) : 1e8f;
+		}
+		else {
+			ext_rgba[a][1] = 0.0f;
+			ext_rgba[a][3] = 0.0f;
+		}
+		print_v4_id(ext_rgba[a]);
+	}
+
+	return GPU_stack_link(mat, node, "curves_rgb", in, out, tex,
+	                                               GPU_constant(&layer),
+	                                               GPU_uniform(range_rgba),
+	                                               GPU_uniform(ext_rgba[0]),
+	                                               GPU_uniform(ext_rgba[1]),
+	                                               GPU_uniform(ext_rgba[2]),
+	                                               GPU_uniform(ext_rgba[3]));
 }
 
 void register_node_type_sh_curve_rgb(void)



More information about the Bf-blender-cvs mailing list