Cycles: RGB and Vector Curves nodes now supported, with the limitation that the

range must be left to the default (0..1 and -1..1).
This commit is contained in:
Brecht Van Lommel
2012-12-11 14:39:37 +00:00
parent 7c81952179
commit 43c04eefe3
11 changed files with 230 additions and 8 deletions

View File

@@ -173,7 +173,6 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
switch(b_node.type()) {
/* not supported */
case BL::ShaderNode::type_CURVE_VEC: break;
case BL::ShaderNode::type_GEOMETRY: break;
case BL::ShaderNode::type_MATERIAL: break;
case BL::ShaderNode::type_MATERIAL_EXT: break;
@@ -193,9 +192,18 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
node = proxy;
break;
}
case BL::ShaderNode::type_CURVE_VEC: {
BL::ShaderNodeVectorCurve b_curve_node(b_node);
VectorCurvesNode *curves = new VectorCurvesNode();
curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, false);
node = curves;
break;
}
case BL::ShaderNode::type_CURVE_RGB: {
RGBCurvesNode *ramp = new RGBCurvesNode();
node = ramp;
BL::ShaderNodeRGBCurve b_curve_node(b_node);
RGBCurvesNode *curves = new RGBCurvesNode();
curvemapping_color_to_array(b_curve_node.mapping(), curves->curves, RAMP_TABLE_SIZE, true);
node = curves;
break;
}
case BL::ShaderNode::type_VALTORGB: {

View File

@@ -52,6 +52,36 @@ static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size
}
}
static inline void curvemapping_color_to_array(BL::CurveMapping cumap, float4 *data, int size, bool rgb_curve)
{
cumap.update();
BL::CurveMap mapR = cumap.curves[0];
BL::CurveMap mapG = cumap.curves[1];
BL::CurveMap mapB = cumap.curves[2];
if(rgb_curve) {
BL::CurveMap mapI = cumap.curves[3];
for(int i = 0; i < size; i++) {
float t = i/(float)(size-1);
data[i][0] = mapR.evaluate(mapI.evaluate(t));
data[i][1] = mapG.evaluate(mapI.evaluate(t));
data[i][2] = mapB.evaluate(mapI.evaluate(t));
}
}
else {
for(int i = 0; i < size; i++) {
float t = i/(float)(size-1);
data[i][0] = mapR.evaluate(t);
data[i][1] = mapG.evaluate(t);
data[i][2] = mapB.evaluate(t);
}
}
}
static inline bool BKE_object_is_modified(BL::Object self, BL::Scene scene, bool preview)
{
return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false;

View File

@@ -49,6 +49,7 @@ set(SRC_OSL
node_output_volume.osl
node_particle_info.osl
node_refraction_bsdf.osl
node_rgb_curves.osl
node_rgb_ramp.osl
node_separate_rgb.osl
node_set_normal.osl
@@ -58,6 +59,7 @@ set(SRC_OSL
node_translucent_bsdf.osl
node_transparent_bsdf.osl
node_value.osl
node_vector_curves.osl
node_vector_math.osl
node_velvet_bsdf.osl
node_voronoi_texture.osl

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "stdosl.h"
#include "oslutil.h"
float ramp_lookup(color ramp[RAMP_TABLE_SIZE], float at, int component)
{
float f = clamp(at, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1);
/* clamp int as well in case of NaN */
int i = (int)f;
if (i < 0) i = 0;
if (i >= RAMP_TABLE_SIZE) i = RAMP_TABLE_SIZE - 1;
float t = f - (float)i;
float result = ramp[i][component];
if (t > 0.0)
result = (1.0 - t) * result + t * ramp[i + 1][component];
return result;
}
shader node_rgb_curves(
color ramp[RAMP_TABLE_SIZE] = {0.0},
color ColorIn = color(0.0, 0.0, 0.0),
float Fac = 0.0,
output color ColorOut = color(0.0, 0.0, 0.0))
{
ColorOut[0] = ramp_lookup(ramp, ColorIn[0], 0);
ColorOut[1] = ramp_lookup(ramp, ColorIn[1], 1);
ColorOut[2] = ramp_lookup(ramp, ColorIn[2], 2);
ColorOut = mix(ColorIn, ColorOut, Fac);
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "stdosl.h"
#include "oslutil.h"
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);
/* clamp int as well in case of NaN */
int i = (int)f;
if (i < 0) i = 0;
if (i >= RAMP_TABLE_SIZE) i = RAMP_TABLE_SIZE - 1;
float t = f - (float)i;
float result = ramp[i][component];
if (t > 0.0)
result = (1.0 - t) * result + t * ramp[i + 1][component];
return result*2.0 - 1.0;
}
shader node_vector_curves(
color ramp[RAMP_TABLE_SIZE] = {0.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);
VectorOut = mix(VectorIn, VectorOut, Fac);
}

View File

@@ -398,6 +398,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_RGB_CURVES:
svm_node_rgb_curves(kg, sd, stack, node, &offset);
break;
case NODE_VECTOR_CURVES:
svm_node_vector_curves(kg, sd, stack, node, &offset);
break;
case NODE_LIGHT_FALLOFF:
svm_node_light_falloff(sd, stack, node);
break;

View File

@@ -63,9 +63,9 @@ __device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stac
float fac = stack_load_float(stack, fac_offset);
float3 color = stack_load_float3(stack, color_offset);
float r = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.x).w).x;
float g = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.y).w).y;
float b = rgb_ramp_lookup(kg, *offset, rgb_ramp_lookup(kg, *offset, color.z).w).z;
float r = rgb_ramp_lookup(kg, *offset, color.x).x;
float g = rgb_ramp_lookup(kg, *offset, color.y).y;
float b = rgb_ramp_lookup(kg, *offset, color.z).z;
color = (1.0f - fac)*color + fac*make_float3(r, g, b);
stack_store_float3(stack, out_offset, color);
@@ -73,6 +73,25 @@ __device void svm_node_rgb_curves(KernelGlobals *kg, ShaderData *sd, float *stac
*offset += RAMP_TABLE_SIZE;
}
__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;
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).x;
float g = rgb_ramp_lookup(kg, *offset, (color.y + 1.0f)*0.5f).y;
float b = rgb_ramp_lookup(kg, *offset, (color.z + 1.0f)*0.5f).z;
color = (1.0f - fac)*color + fac*make_float3(r*2.0f - 1.0f, g*2.0f - 1.0f, b*2.0f - 1.0f);
stack_store_float3(stack, out_offset, color);
*offset += RAMP_TABLE_SIZE;
}
CCL_NAMESPACE_END
#endif /* __SVM_RAMP_H__ */

View File

@@ -88,6 +88,7 @@ typedef enum NodeType {
NODE_BRIGHTCONTRAST,
NODE_RGB_RAMP,
NODE_RGB_CURVES,
NODE_VECTOR_CURVES,
NODE_MIN_MAX,
NODE_LIGHT_FALLOFF,
NODE_OBJECT_INFO,

View File

@@ -3018,9 +3018,56 @@ void RGBCurvesNode::compile(SVMCompiler& compiler)
void RGBCurvesNode::compile(OSLCompiler& compiler)
{
float ramp[RAMP_TABLE_SIZE][3];
for (int i = 0; i < RAMP_TABLE_SIZE; ++i) {
ramp[i][0] = curves[i].x;
ramp[i][1] = curves[i].y;
ramp[i][2] = curves[i].z;
}
compiler.parameter_color_array("ramp", ramp, RAMP_TABLE_SIZE);
compiler.add(this, "node_rgb_curves");
}
/* VectorCurvesNode */
VectorCurvesNode::VectorCurvesNode()
: ShaderNode("rgb_curves")
{
add_input("Fac", SHADER_SOCKET_FLOAT);
add_input("Vector", SHADER_SOCKET_VECTOR);
add_output("Vector", SHADER_SOCKET_VECTOR);
}
void VectorCurvesNode::compile(SVMCompiler& compiler)
{
ShaderInput *fac_in = input("Fac");
ShaderInput *vector_in = input("Vector");
ShaderOutput *vector_out = output("Vector");
compiler.stack_assign(fac_in);
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_array(curves, RAMP_TABLE_SIZE);
}
void VectorCurvesNode::compile(OSLCompiler& compiler)
{
float ramp[RAMP_TABLE_SIZE][3];
for (int i = 0; i < RAMP_TABLE_SIZE; ++i) {
ramp[i][0] = curves[i].x;
ramp[i][1] = curves[i].y;
ramp[i][2] = curves[i].z;
}
compiler.parameter_color_array("ramp", ramp, RAMP_TABLE_SIZE);
compiler.add(this, "node_vector_curves");
}
/* RGBRampNode */
RGBRampNode::RGBRampNode()

View File

@@ -455,6 +455,12 @@ public:
float4 curves[RAMP_TABLE_SIZE];
};
class VectorCurvesNode : public ShaderNode {
public:
SHADER_NODE_CLASS(VectorCurvesNode)
float4 curves[RAMP_TABLE_SIZE];
};
class RGBRampNode : public ShaderNode {
public:
SHADER_NODE_CLASS(RGBRampNode)

View File

@@ -74,7 +74,7 @@ void register_node_type_sh_curve_vec(bNodeTreeType *ttype)
static bNodeType ntype;
node_type_base(ttype, &ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS);
node_type_compatibility(&ntype, NODE_OLD_SHADING);
node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_curve_vec_in, sh_node_curve_vec_out);
node_type_size(&ntype, 200, 140, 320);
node_type_init(&ntype, node_shader_init_curve_vec);
@@ -132,7 +132,7 @@ void register_node_type_sh_curve_rgb(bNodeTreeType *ttype)
static bNodeType ntype;
node_type_base(ttype, &ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_compatibility(&ntype, NODE_OLD_SHADING);
node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_curve_rgb_in, sh_node_curve_rgb_out);
node_type_size(&ntype, 200, 140, 320);
node_type_init(&ntype, node_shader_init_curve_rgb);