Fix T96132: Cycles RGB/Vector/Float Curve shaders ignore extrapolation setting
Differential Revision: https://developer.blender.org/D14393
This commit is contained in:

committed by
Brecht Van Lommel

parent
f92e3b39f1
commit
c7e25a25b0
@@ -271,6 +271,7 @@ static ShaderNode *add_node(Scene *scene,
|
|||||||
curves->set_min_x(min_x);
|
curves->set_min_x(min_x);
|
||||||
curves->set_max_x(max_x);
|
curves->set_max_x(max_x);
|
||||||
curves->set_curves(curve_mapping_curves);
|
curves->set_curves(curve_mapping_curves);
|
||||||
|
curves->set_extrapolate(mapping.extend() == mapping.extend_EXTRAPOLATED);
|
||||||
node = curves;
|
node = curves;
|
||||||
}
|
}
|
||||||
if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
|
if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) {
|
||||||
@@ -284,6 +285,7 @@ static ShaderNode *add_node(Scene *scene,
|
|||||||
curves->set_min_x(min_x);
|
curves->set_min_x(min_x);
|
||||||
curves->set_max_x(max_x);
|
curves->set_max_x(max_x);
|
||||||
curves->set_curves(curve_mapping_curves);
|
curves->set_curves(curve_mapping_curves);
|
||||||
|
curves->set_extrapolate(mapping.extend() == mapping.extend_EXTRAPOLATED);
|
||||||
node = curves;
|
node = curves;
|
||||||
}
|
}
|
||||||
else if (b_node.is_a(&RNA_ShaderNodeFloatCurve)) {
|
else if (b_node.is_a(&RNA_ShaderNodeFloatCurve)) {
|
||||||
@@ -297,6 +299,7 @@ static ShaderNode *add_node(Scene *scene,
|
|||||||
curve->set_min_x(min_x);
|
curve->set_min_x(min_x);
|
||||||
curve->set_max_x(max_x);
|
curve->set_max_x(max_x);
|
||||||
curve->set_curve(curve_mapping_curve);
|
curve->set_curve(curve_mapping_curve);
|
||||||
|
curve->set_extrapolate(mapping.extend() == mapping.extend_EXTRAPOLATED);
|
||||||
node = curve;
|
node = curve;
|
||||||
}
|
}
|
||||||
else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
|
else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
|
||||||
|
@@ -7,13 +7,15 @@
|
|||||||
shader node_float_curve(float ramp[] = {0.0},
|
shader node_float_curve(float ramp[] = {0.0},
|
||||||
float min_x = 0.0,
|
float min_x = 0.0,
|
||||||
float max_x = 1.0,
|
float max_x = 1.0,
|
||||||
|
int extrapolate = 1,
|
||||||
|
|
||||||
float ValueIn = 0.0,
|
float ValueIn = 0.0,
|
||||||
float Factor = 0.0,
|
float Factor = 0.0,
|
||||||
output float ValueOut = 0.0)
|
output float ValueOut = 0.0)
|
||||||
{
|
{
|
||||||
float c = (ValueIn - min_x) / (max_x - min_x);
|
float c = (ValueIn - min_x) / (max_x - min_x);
|
||||||
|
|
||||||
ValueOut = rgb_ramp_lookup(ramp, c, 1, 1);
|
ValueOut = rgb_ramp_lookup(ramp, c, 1, extrapolate);
|
||||||
|
|
||||||
ValueOut = mix(ValueIn, ValueOut, Factor);
|
ValueOut = mix(ValueIn, ValueOut, Factor);
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
shader node_rgb_curves(color ramp[] = {0.0},
|
shader node_rgb_curves(color ramp[] = {0.0},
|
||||||
float min_x = 0.0,
|
float min_x = 0.0,
|
||||||
float max_x = 1.0,
|
float max_x = 1.0,
|
||||||
|
int extrapolate = 1,
|
||||||
|
|
||||||
color ColorIn = 0.0,
|
color ColorIn = 0.0,
|
||||||
float Fac = 0.0,
|
float Fac = 0.0,
|
||||||
@@ -14,9 +15,9 @@ shader node_rgb_curves(color ramp[] = {0.0},
|
|||||||
{
|
{
|
||||||
color c = (ColorIn - color(min_x, min_x, min_x)) / (max_x - min_x);
|
color c = (ColorIn - color(min_x, min_x, min_x)) / (max_x - min_x);
|
||||||
|
|
||||||
color r = rgb_ramp_lookup(ramp, c[0], 1, 1);
|
color r = rgb_ramp_lookup(ramp, c[0], 1, extrapolate);
|
||||||
color g = rgb_ramp_lookup(ramp, c[1], 1, 1);
|
color g = rgb_ramp_lookup(ramp, c[1], 1, extrapolate);
|
||||||
color b = rgb_ramp_lookup(ramp, c[2], 1, 1);
|
color b = rgb_ramp_lookup(ramp, c[2], 1, extrapolate);
|
||||||
|
|
||||||
ColorOut[0] = r[0];
|
ColorOut[0] = r[0];
|
||||||
ColorOut[1] = g[1];
|
ColorOut[1] = g[1];
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
shader node_vector_curves(color ramp[] = {0.0},
|
shader node_vector_curves(color ramp[] = {0.0},
|
||||||
float min_x = 0.0,
|
float min_x = 0.0,
|
||||||
float max_x = 1.0,
|
float max_x = 1.0,
|
||||||
|
int extrapolate = 1,
|
||||||
|
|
||||||
vector VectorIn = vector(0.0, 0.0, 0.0),
|
vector VectorIn = vector(0.0, 0.0, 0.0),
|
||||||
float Fac = 0.0,
|
float Fac = 0.0,
|
||||||
@@ -14,9 +15,9 @@ shader node_vector_curves(color ramp[] = {0.0},
|
|||||||
{
|
{
|
||||||
vector c = (VectorIn - vector(min_x, min_x, min_x)) / (max_x - min_x);
|
vector c = (VectorIn - vector(min_x, min_x, min_x)) / (max_x - min_x);
|
||||||
|
|
||||||
color r = rgb_ramp_lookup(ramp, c[0], 1, 1);
|
color r = rgb_ramp_lookup(ramp, c[0], 1, extrapolate);
|
||||||
color g = rgb_ramp_lookup(ramp, c[0], 1, 1);
|
color g = rgb_ramp_lookup(ramp, c[0], 1, extrapolate);
|
||||||
color b = rgb_ramp_lookup(ramp, c[0], 1, 1);
|
color b = rgb_ramp_lookup(ramp, c[0], 1, extrapolate);
|
||||||
|
|
||||||
VectorOut[0] = r[0];
|
VectorOut[0] = r[0];
|
||||||
VectorOut[1] = g[1];
|
VectorOut[1] = g[1];
|
||||||
|
@@ -102,8 +102,8 @@ ccl_device_noinline int svm_node_rgb_ramp(
|
|||||||
ccl_device_noinline int svm_node_curves(
|
ccl_device_noinline int svm_node_curves(
|
||||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||||
{
|
{
|
||||||
uint fac_offset, color_offset, out_offset;
|
uint fac_offset, color_offset, out_offset, extrapolate;
|
||||||
svm_unpack_node_uchar3(node.y, &fac_offset, &color_offset, &out_offset);
|
svm_unpack_node_uchar4(node.y, &fac_offset, &color_offset, &out_offset, &extrapolate);
|
||||||
|
|
||||||
uint table_size = read_node(kg, &offset).x;
|
uint table_size = read_node(kg, &offset).x;
|
||||||
|
|
||||||
@@ -114,9 +114,9 @@ ccl_device_noinline int svm_node_curves(
|
|||||||
const float range_x = max_x - min_x;
|
const float range_x = max_x - min_x;
|
||||||
const float3 relpos = (color - make_float3(min_x, min_x, min_x)) / range_x;
|
const float3 relpos = (color - make_float3(min_x, min_x, min_x)) / range_x;
|
||||||
|
|
||||||
float r = rgb_ramp_lookup(kg, offset, relpos.x, true, true, table_size).x;
|
float r = rgb_ramp_lookup(kg, offset, relpos.x, true, extrapolate, table_size).x;
|
||||||
float g = rgb_ramp_lookup(kg, offset, relpos.y, true, true, table_size).y;
|
float g = rgb_ramp_lookup(kg, offset, relpos.y, true, extrapolate, table_size).y;
|
||||||
float b = rgb_ramp_lookup(kg, offset, relpos.z, true, true, table_size).z;
|
float b = rgb_ramp_lookup(kg, offset, relpos.z, true, extrapolate, table_size).z;
|
||||||
|
|
||||||
color = (1.0f - fac) * color + fac * make_float3(r, g, b);
|
color = (1.0f - fac) * color + fac * make_float3(r, g, b);
|
||||||
stack_store_float3(stack, out_offset, color);
|
stack_store_float3(stack, out_offset, color);
|
||||||
@@ -128,8 +128,8 @@ ccl_device_noinline int svm_node_curves(
|
|||||||
ccl_device_noinline int svm_node_curve(
|
ccl_device_noinline int svm_node_curve(
|
||||||
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset)
|
||||||
{
|
{
|
||||||
uint fac_offset, value_in_offset, out_offset;
|
uint fac_offset, value_in_offset, out_offset, extrapolate;
|
||||||
svm_unpack_node_uchar3(node.y, &fac_offset, &value_in_offset, &out_offset);
|
svm_unpack_node_uchar4(node.y, &fac_offset, &value_in_offset, &out_offset, &extrapolate);
|
||||||
|
|
||||||
uint table_size = read_node(kg, &offset).x;
|
uint table_size = read_node(kg, &offset).x;
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ ccl_device_noinline int svm_node_curve(
|
|||||||
const float range = max - min;
|
const float range = max - min;
|
||||||
const float relpos = (in - min) / range;
|
const float relpos = (in - min) / range;
|
||||||
|
|
||||||
float v = float_ramp_lookup(kg, offset, relpos, true, true, table_size);
|
float v = float_ramp_lookup(kg, offset, relpos, true, extrapolate, table_size);
|
||||||
|
|
||||||
in = (1.0f - fac) * in + fac * v;
|
in = (1.0f - fac) * in + fac * v;
|
||||||
stack_store_float(stack, out_offset, in);
|
stack_store_float(stack, out_offset, in);
|
||||||
|
@@ -6529,9 +6529,9 @@ void CurvesNode::constant_fold(const ConstantFolder &folder, ShaderInput *value_
|
|||||||
float3 pos = (value - make_float3(min_x, min_x, min_x)) / (max_x - min_x);
|
float3 pos = (value - make_float3(min_x, min_x, min_x)) / (max_x - min_x);
|
||||||
float3 result;
|
float3 result;
|
||||||
|
|
||||||
result[0] = rgb_ramp_lookup(curves.data(), pos[0], true, true, curves.size()).x;
|
result[0] = rgb_ramp_lookup(curves.data(), pos[0], true, extrapolate, curves.size()).x;
|
||||||
result[1] = rgb_ramp_lookup(curves.data(), pos[1], true, true, curves.size()).y;
|
result[1] = rgb_ramp_lookup(curves.data(), pos[1], true, extrapolate, curves.size()).y;
|
||||||
result[2] = rgb_ramp_lookup(curves.data(), pos[2], true, true, curves.size()).z;
|
result[2] = rgb_ramp_lookup(curves.data(), pos[2], true, extrapolate, curves.size()).z;
|
||||||
|
|
||||||
folder.make_constant(interp(value, result, fac));
|
folder.make_constant(interp(value, result, fac));
|
||||||
}
|
}
|
||||||
@@ -6555,7 +6555,8 @@ void CurvesNode::compile(SVMCompiler &compiler,
|
|||||||
compiler.add_node(type,
|
compiler.add_node(type,
|
||||||
compiler.encode_uchar4(compiler.stack_assign(fac_in),
|
compiler.encode_uchar4(compiler.stack_assign(fac_in),
|
||||||
compiler.stack_assign(value_in),
|
compiler.stack_assign(value_in),
|
||||||
compiler.stack_assign(value_out)),
|
compiler.stack_assign(value_out),
|
||||||
|
extrapolate),
|
||||||
__float_as_int(min_x),
|
__float_as_int(min_x),
|
||||||
__float_as_int(max_x));
|
__float_as_int(max_x));
|
||||||
|
|
||||||
@@ -6572,6 +6573,7 @@ void CurvesNode::compile(OSLCompiler &compiler, const char *name)
|
|||||||
compiler.parameter_color_array("ramp", curves);
|
compiler.parameter_color_array("ramp", curves);
|
||||||
compiler.parameter(this, "min_x");
|
compiler.parameter(this, "min_x");
|
||||||
compiler.parameter(this, "max_x");
|
compiler.parameter(this, "max_x");
|
||||||
|
compiler.parameter(this, "extrapolate");
|
||||||
compiler.add(this, name);
|
compiler.add(this, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6594,6 +6596,7 @@ NODE_DEFINE(RGBCurvesNode)
|
|||||||
SOCKET_COLOR_ARRAY(curves, "Curves", array<float3>());
|
SOCKET_COLOR_ARRAY(curves, "Curves", array<float3>());
|
||||||
SOCKET_FLOAT(min_x, "Min X", 0.0f);
|
SOCKET_FLOAT(min_x, "Min X", 0.0f);
|
||||||
SOCKET_FLOAT(max_x, "Max X", 1.0f);
|
SOCKET_FLOAT(max_x, "Max X", 1.0f);
|
||||||
|
SOCKET_BOOLEAN(extrapolate, "Extrapolate", true);
|
||||||
|
|
||||||
SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
|
SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
|
||||||
SOCKET_IN_COLOR(value, "Color", zero_float3());
|
SOCKET_IN_COLOR(value, "Color", zero_float3());
|
||||||
@@ -6631,6 +6634,7 @@ NODE_DEFINE(VectorCurvesNode)
|
|||||||
SOCKET_VECTOR_ARRAY(curves, "Curves", array<float3>());
|
SOCKET_VECTOR_ARRAY(curves, "Curves", array<float3>());
|
||||||
SOCKET_FLOAT(min_x, "Min X", 0.0f);
|
SOCKET_FLOAT(min_x, "Min X", 0.0f);
|
||||||
SOCKET_FLOAT(max_x, "Max X", 1.0f);
|
SOCKET_FLOAT(max_x, "Max X", 1.0f);
|
||||||
|
SOCKET_BOOLEAN(extrapolate, "Extrapolate", true);
|
||||||
|
|
||||||
SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
|
SOCKET_IN_FLOAT(fac, "Fac", 0.0f);
|
||||||
SOCKET_IN_VECTOR(value, "Vector", zero_float3());
|
SOCKET_IN_VECTOR(value, "Vector", zero_float3());
|
||||||
@@ -6668,6 +6672,7 @@ NODE_DEFINE(FloatCurveNode)
|
|||||||
SOCKET_FLOAT_ARRAY(curve, "Curve", array<float>());
|
SOCKET_FLOAT_ARRAY(curve, "Curve", array<float>());
|
||||||
SOCKET_FLOAT(min_x, "Min X", 0.0f);
|
SOCKET_FLOAT(min_x, "Min X", 0.0f);
|
||||||
SOCKET_FLOAT(max_x, "Max X", 1.0f);
|
SOCKET_FLOAT(max_x, "Max X", 1.0f);
|
||||||
|
SOCKET_BOOLEAN(extrapolate, "Extrapolate", true);
|
||||||
|
|
||||||
SOCKET_IN_FLOAT(fac, "Factor", 0.0f);
|
SOCKET_IN_FLOAT(fac, "Factor", 0.0f);
|
||||||
SOCKET_IN_FLOAT(value, "Value", 0.0f);
|
SOCKET_IN_FLOAT(value, "Value", 0.0f);
|
||||||
@@ -6693,7 +6698,7 @@ void FloatCurveNode::constant_fold(const ConstantFolder &folder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
float pos = (value - min_x) / (max_x - min_x);
|
float pos = (value - min_x) / (max_x - min_x);
|
||||||
float result = float_ramp_lookup(curve.data(), pos, true, true, curve.size());
|
float result = float_ramp_lookup(curve.data(), pos, true, extrapolate, curve.size());
|
||||||
|
|
||||||
folder.make_constant(value + fac * (result - value));
|
folder.make_constant(value + fac * (result - value));
|
||||||
}
|
}
|
||||||
@@ -6716,7 +6721,8 @@ void FloatCurveNode::compile(SVMCompiler &compiler)
|
|||||||
compiler.add_node(NODE_FLOAT_CURVE,
|
compiler.add_node(NODE_FLOAT_CURVE,
|
||||||
compiler.encode_uchar4(compiler.stack_assign(fac_in),
|
compiler.encode_uchar4(compiler.stack_assign(fac_in),
|
||||||
compiler.stack_assign(value_in),
|
compiler.stack_assign(value_in),
|
||||||
compiler.stack_assign(value_out)),
|
compiler.stack_assign(value_out),
|
||||||
|
extrapolate),
|
||||||
__float_as_int(min_x),
|
__float_as_int(min_x),
|
||||||
__float_as_int(max_x));
|
__float_as_int(max_x));
|
||||||
|
|
||||||
@@ -6733,6 +6739,7 @@ void FloatCurveNode::compile(OSLCompiler &compiler)
|
|||||||
compiler.parameter_array("ramp", curve.data(), curve.size());
|
compiler.parameter_array("ramp", curve.data(), curve.size());
|
||||||
compiler.parameter(this, "min_x");
|
compiler.parameter(this, "min_x");
|
||||||
compiler.parameter(this, "max_x");
|
compiler.parameter(this, "max_x");
|
||||||
|
compiler.parameter(this, "extrapolate");
|
||||||
compiler.add(this, "node_float_curve");
|
compiler.add(this, "node_float_curve");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1391,6 +1391,7 @@ class CurvesNode : public ShaderNode {
|
|||||||
NODE_SOCKET_API(float, max_x)
|
NODE_SOCKET_API(float, max_x)
|
||||||
NODE_SOCKET_API(float, fac)
|
NODE_SOCKET_API(float, fac)
|
||||||
NODE_SOCKET_API(float3, value)
|
NODE_SOCKET_API(float3, value)
|
||||||
|
NODE_SOCKET_API(bool, extrapolate)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using ShaderNode::constant_fold;
|
using ShaderNode::constant_fold;
|
||||||
@@ -1421,6 +1422,7 @@ class FloatCurveNode : public ShaderNode {
|
|||||||
NODE_SOCKET_API(float, max_x)
|
NODE_SOCKET_API(float, max_x)
|
||||||
NODE_SOCKET_API(float, fac)
|
NODE_SOCKET_API(float, fac)
|
||||||
NODE_SOCKET_API(float, value)
|
NODE_SOCKET_API(float, value)
|
||||||
|
NODE_SOCKET_API(bool, extrapolate)
|
||||||
};
|
};
|
||||||
|
|
||||||
class RGBRampNode : public ShaderNode {
|
class RGBRampNode : public ShaderNode {
|
||||||
|
Reference in New Issue
Block a user