diff options
-rw-r--r-- | intern/cycles/blender/addon/version_update.py | 16 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 7 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 29 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_vector_curves.osl | 29 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_ramp.h | 22 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_blender.h | 2 |
8 files changed, 88 insertions, 30 deletions
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index 2fbb01ba5b8..eb6d5d957ad 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -100,6 +100,19 @@ def mapping_node_order_flip(node): node.rotation = quat.to_euler('XYZ') +def vector_curve_node_remap(node): + """ + Remap values of vector curve node from normalized to absolute values + """ + from mathutils import Vector + if node.bl_idname == 'ShaderNodeVectorCurve': + node.mapping.use_clip = False + for curve in node.mapping.curves: + for point in curve.points: + point.location.x = (point.location.x * 2.0) - 1.0 + point.location.y = (point.location.y - 0.5) * 2.0 + node.mapping.update() + @persistent def do_versions(self): # We don't modify startup file because it assumes to @@ -140,3 +153,6 @@ def do_versions(self): # Euler order was ZYX in previous versions. if bpy.data.version <= (2, 73, 4): foreach_cycles_node(mapping_node_order_flip) + + if bpy.data.version <= (2, 76, 5): + foreach_cycles_node(vector_curve_node_remap) diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 74dee206c0e..2b4d0e4af9c 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -231,8 +231,13 @@ static ShaderNode *add_node(Scene *scene, } if(b_node.is_a(&RNA_ShaderNodeVectorCurve)) { BL::ShaderNodeVectorCurve b_curve_node(b_node); + BL::CurveMapping mapping(b_curve_node.mapping()); VectorCurvesNode *curves = new VectorCurvesNode(); - curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, false); + curvemapping_color_to_array(mapping, + curves->curves, + RAMP_TABLE_SIZE, + false); + curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x); node = curves; } else if(b_node.is_a(&RNA_ShaderNodeValToRGB)) { diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 029d0af0fd2..a1508fc6a07 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -101,21 +101,20 @@ static inline void curvemapping_color_to_array(BL::CurveMapping cumap, bool rgb_curve) { float min_x = 0.0f, max_x = 1.0f; - /* TODO(sergey): Vector curve mapping is still clipping to 0..1. */ - if(rgb_curve) { - /* TODO(sergey): There is no easy way to automatically guess what is - * the range to be used here for the case when mapping is applied on - * top of another mapping (i.e. R curve applied on top of common - * one). - * - * Using largest possible range form all curves works correct for the - * cases like vector curves and should be good enough heuristic for - * the color curves as well. - * - * There might be some better estimations here tho. - */ - curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x); - } + + /* TODO(sergey): There is no easy way to automatically guess what is + * the range to be used here for the case when mapping is applied on + * top of another mapping (i.e. R curve applied on top of common + * one). + * + * Using largest possible range form all curves works correct for the + * cases like vector curves and should be good enough heuristic for + * the color curves as well. + * + * There might be some better estimations here tho. + */ + curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x); + const float range_x = max_x - min_x; cumap.update(); diff --git a/intern/cycles/kernel/shaders/node_vector_curves.osl b/intern/cycles/kernel/shaders/node_vector_curves.osl index 7bbf97d95ea..65a59dec983 100644 --- a/intern/cycles/kernel/shaders/node_vector_curves.osl +++ b/intern/cycles/kernel/shaders/node_vector_curves.osl @@ -19,7 +19,22 @@ float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component) { - float f = clamp((at + 1.0) * 0.5, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1); + if (at < 0.0 || at > 1.0) { + float t0, dy; + if(at < 0.0) { + t0 = ramp[0][component]; + dy = t0 - ramp[1][component]; + at = -at; + } + else { + t0 = ramp[RAMP_TABLE_SIZE - 1][component]; + dy = t0 - ramp[RAMP_TABLE_SIZE - 2][component]; + at = at - 1.0; + } + return t0 + dy * at * (RAMP_TABLE_SIZE - 1); + } + + float f = clamp(at, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1); /* clamp int as well in case of NaN */ int i = (int)f; @@ -32,19 +47,23 @@ float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component) if (t > 0.0) result = (1.0 - t) * result + t * ramp[i + 1][component]; - return result * 2.0 - 1.0; + return result; } shader node_vector_curves( color ramp[RAMP_TABLE_SIZE] = {0.0}, + float min_x = 0.0, + float max_x = 1.0, vector VectorIn = vector(0.0, 0.0, 0.0), float Fac = 0.0, output vector VectorOut = vector(0.0, 0.0, 0.0)) { - VectorOut[0] = ramp_lookup(ramp, VectorIn[0], 0); - VectorOut[1] = ramp_lookup(ramp, VectorIn[1], 1); - VectorOut[2] = ramp_lookup(ramp, VectorIn[2], 2); + color c = (VectorIn - vector(min_x, min_x, min_x)) / (max_x - min_x); + + VectorOut[0] = ramp_lookup(ramp, c[0], 0); + VectorOut[1] = ramp_lookup(ramp, c[1], 1); + VectorOut[2] = ramp_lookup(ramp, c[2], 2); VectorOut = mix(VectorIn, VectorOut, Fac); } diff --git a/intern/cycles/kernel/svm/svm_ramp.h b/intern/cycles/kernel/svm/svm_ramp.h index 48d969947f5..7e4106e212e 100644 --- a/intern/cycles/kernel/svm/svm_ramp.h +++ b/intern/cycles/kernel/svm/svm_ramp.h @@ -101,18 +101,26 @@ ccl_device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *st ccl_device void svm_node_vector_curves(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint fac_offset = node.y; - uint color_offset = node.z; - uint out_offset = node.w; + uint fac_offset, color_offset, out_offset; + decode_node_uchar4(node.y, + &fac_offset, + &color_offset, + &out_offset, + NULL); float fac = stack_load_float(stack, fac_offset); float3 color = stack_load_float3(stack, color_offset); - float r = rgb_ramp_lookup(kg, *offset, (color.x + 1.0f)*0.5f, true, false).x; - float g = rgb_ramp_lookup(kg, *offset, (color.y + 1.0f)*0.5f, true, false).y; - float b = rgb_ramp_lookup(kg, *offset, (color.z + 1.0f)*0.5f, true, false).z; + const float min_x = __int_as_float(node.z), + max_x = __int_as_float(node.w); + const float range_x = max_x - min_x; + color = (color - make_float3(min_x, min_x, min_x)) / range_x; - color = (1.0f - fac)*color + fac*make_float3(r*2.0f - 1.0f, g*2.0f - 1.0f, b*2.0f - 1.0f); + float r = rgb_ramp_lookup(kg, *offset, color.x, true, true).x; + float g = rgb_ramp_lookup(kg, *offset, color.y, true, true).y; + float b = rgb_ramp_lookup(kg, *offset, color.z, true, true).z; + + color = (1.0f - fac)*color + fac*make_float3(r, g, b); stack_store_float3(stack, out_offset, color); *offset += RAMP_TABLE_SIZE; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 870efda7b80..92ade79781a 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -4443,6 +4443,9 @@ VectorCurvesNode::VectorCurvesNode() add_input("Fac", SHADER_SOCKET_FLOAT); add_input("Vector", SHADER_SOCKET_VECTOR); add_output("Vector", SHADER_SOCKET_VECTOR); + + min_x = 0.0f; + max_x = 1.0f; } void VectorCurvesNode::compile(SVMCompiler& compiler) @@ -4455,7 +4458,12 @@ void VectorCurvesNode::compile(SVMCompiler& compiler) compiler.stack_assign(vector_in); compiler.stack_assign(vector_out); - compiler.add_node(NODE_VECTOR_CURVES, fac_in->stack_offset, vector_in->stack_offset, vector_out->stack_offset); + compiler.add_node(NODE_VECTOR_CURVES, + compiler.encode_uchar4(fac_in->stack_offset, + vector_in->stack_offset, + vector_out->stack_offset), + __float_as_int(min_x), + __float_as_int(max_x)); compiler.add_array(curves, RAMP_TABLE_SIZE); } @@ -4470,6 +4478,8 @@ void VectorCurvesNode::compile(OSLCompiler& compiler) } compiler.parameter_color_array("ramp", ramp, RAMP_TABLE_SIZE); + compiler.parameter("min_x", min_x); + compiler.parameter("max_x", max_x); compiler.add(this, "node_vector_curves"); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 4eddc90be3f..67943775b92 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -946,6 +946,7 @@ public: virtual bool equals(const ShaderNode * /*other*/) { return false; } float4 curves[RAMP_TABLE_SIZE]; + float min_x, max_x; }; class RGBRampNode : public ShaderNode { diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 9efaad81feb..aaf47b65470 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -45,7 +45,7 @@ extern "C" { #define BLENDER_SUBVERSION 5 /* Several breakages with 270, e.g. constraint deg vs rad */ #define BLENDER_MINVERSION 270 -#define BLENDER_MINSUBVERSION 5 +#define BLENDER_MINSUBVERSION 6 /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ |