diff options
Diffstat (limited to 'intern/cycles/render/nodes.cpp')
-rw-r--r-- | intern/cycles/render/nodes.cpp | 429 |
1 files changed, 410 insertions, 19 deletions
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 4e16eea2774..82afab4dc1a 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -225,6 +225,8 @@ void ImageTextureNode::compile(OSLCompiler& compiler) compiler.parameter("color_space", "Linear"); else compiler.parameter("color_space", "sRGB"); + compiler.parameter("projection", projection); + compiler.parameter("projection_blend", projection_blend); compiler.add(this, "node_image_texture"); } @@ -1065,6 +1067,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_) if(from == SHADER_SOCKET_FLOAT) add_input("Val", SHADER_SOCKET_FLOAT); + else if(from == SHADER_SOCKET_INT) + add_input("ValInt", SHADER_SOCKET_INT); else if(from == SHADER_SOCKET_COLOR) add_input("Color", SHADER_SOCKET_COLOR); else if(from == SHADER_SOCKET_VECTOR) @@ -1078,6 +1082,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_) if(to == SHADER_SOCKET_FLOAT) add_output("Val", SHADER_SOCKET_FLOAT); + else if(to == SHADER_SOCKET_INT) + add_output("ValInt", SHADER_SOCKET_INT); else if(to == SHADER_SOCKET_COLOR) add_output("Color", SHADER_SOCKET_COLOR); else if(to == SHADER_SOCKET_VECTOR) @@ -1095,7 +1101,29 @@ void ConvertNode::compile(SVMCompiler& compiler) ShaderInput *in = inputs[0]; ShaderOutput *out = outputs[0]; - if(to == SHADER_SOCKET_FLOAT) { + if(from == SHADER_SOCKET_FLOAT) { + compiler.stack_assign(in); + compiler.stack_assign(out); + + if(to == SHADER_SOCKET_INT) + /* float to int */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_FI, in->stack_offset, out->stack_offset); + else + /* float to float3 */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset); + } + else if(from == SHADER_SOCKET_INT) { + compiler.stack_assign(in); + compiler.stack_assign(out); + + if(to == SHADER_SOCKET_FLOAT) + /* int to float */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_IF, in->stack_offset, out->stack_offset); + else + /* int to vector/point/normal */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_IV, in->stack_offset, out->stack_offset); + } + else if(to == SHADER_SOCKET_FLOAT) { compiler.stack_assign(in); compiler.stack_assign(out); @@ -1106,12 +1134,16 @@ void ConvertNode::compile(SVMCompiler& compiler) /* vector/point/normal to float */ compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, in->stack_offset, out->stack_offset); } - else if(from == SHADER_SOCKET_FLOAT) { + else if(to == SHADER_SOCKET_INT) { compiler.stack_assign(in); compiler.stack_assign(out); - /* float to float3 */ - compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset); + if(from == SHADER_SOCKET_COLOR) + /* color to int */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_CI, in->stack_offset, out->stack_offset); + else + /* vector/point/normal to int */ + compiler.add_node(NODE_CONVERT, NODE_CONVERT_VI, in->stack_offset, out->stack_offset); } else { /* float3 to float3 */ @@ -1134,6 +1166,8 @@ void ConvertNode::compile(OSLCompiler& compiler) { if(from == SHADER_SOCKET_FLOAT) compiler.add(this, "node_convert_from_float"); + else if(from == SHADER_SOCKET_INT) + compiler.add(this, "node_convert_from_int"); else if(from == SHADER_SOCKET_COLOR) compiler.add(this, "node_convert_from_color"); else if(from == SHADER_SOCKET_VECTOR) @@ -1175,14 +1209,16 @@ BsdfNode::BsdfNode() closure = ccl::CLOSURE_BSDF_DIFFUSE_ID; add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); add_output("BSDF", SHADER_SOCKET_CLOSURE); } -void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2) +void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3) { ShaderInput *color_in = input("Color"); + ShaderInput *normal_in = input("Normal"); + ShaderInput *tangent_in = input("Tangent"); if(color_in->link) { compiler.stack_assign(color_in); @@ -1195,6 +1231,14 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput * compiler.stack_assign(param1); if(param2) compiler.stack_assign(param2); + if(param3) + compiler.stack_assign(param3); + + if(normal_in->link) + compiler.stack_assign(normal_in); + + if(tangent_in && tangent_in->link) + compiler.stack_assign(tangent_in); compiler.add_node(NODE_CLOSURE_BSDF, compiler.encode_uchar4(closure, @@ -1203,6 +1247,14 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput * compiler.closure_mix_weight_offset()), __float_as_int((param1)? param1->value.x: 0.0f), __float_as_int((param2)? param2->value.x: 0.0f)); + + if(tangent_in) { + compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset, + (param3)? param3->stack_offset: SVM_STACK_INVALID); + } + else { + compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset); + } } void BsdfNode::compile(SVMCompiler& compiler) @@ -1221,13 +1273,26 @@ WardBsdfNode::WardBsdfNode() { closure = CLOSURE_BSDF_WARD_ID; - add_input("Roughness U", SHADER_SOCKET_FLOAT, 0.2f); - add_input("Roughness V", SHADER_SOCKET_FLOAT, 0.2f); + add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT); + + add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f); + add_input("Anisotropy", SHADER_SOCKET_FLOAT, 0.5f); + add_input("Rotation", SHADER_SOCKET_FLOAT, 0.0f); +} + +void WardBsdfNode::attributes(AttributeRequestSet *attributes) +{ + ShaderInput *tangent_in = input("Tangent"); + + if(!tangent_in->link) + attributes->add(ATTR_STD_GENERATED); + + ShaderNode::attributes(attributes); } void WardBsdfNode::compile(SVMCompiler& compiler) { - BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V")); + BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation")); } void WardBsdfNode::compile(OSLCompiler& compiler) @@ -1279,9 +1344,9 @@ static ShaderEnum glass_distribution_init() { ShaderEnum enm; - enm.insert("Sharp", CLOSURE_BSDF_REFRACTION_ID); - enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID); - enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID); + enm.insert("Sharp", CLOSURE_BSDF_SHARP_GLASS_ID); + enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID); + enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); return enm; } @@ -1300,7 +1365,7 @@ void GlassBsdfNode::compile(SVMCompiler& compiler) { closure = (ClosureType)distribution_enum[distribution]; - if(closure == CLOSURE_BSDF_REFRACTION_ID) + if(closure == CLOSURE_BSDF_SHARP_GLASS_ID) BsdfNode::compile(compiler, NULL, input("IOR")); else BsdfNode::compile(compiler, input("Roughness"), input("IOR")); @@ -1312,6 +1377,45 @@ void GlassBsdfNode::compile(OSLCompiler& compiler) compiler.add(this, "node_glass_bsdf"); } +/* Refraction BSDF Closure */ + +static ShaderEnum refraction_distribution_init() +{ + ShaderEnum enm; + + enm.insert("Sharp", CLOSURE_BSDF_REFRACTION_ID); + enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID); + enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID); + + return enm; +} + +ShaderEnum RefractionBsdfNode::distribution_enum = refraction_distribution_init(); + +RefractionBsdfNode::RefractionBsdfNode() +{ + distribution = ustring("Sharp"); + + add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f); + add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f); +} + +void RefractionBsdfNode::compile(SVMCompiler& compiler) +{ + closure = (ClosureType)distribution_enum[distribution]; + + if(closure == CLOSURE_BSDF_REFRACTION_ID) + BsdfNode::compile(compiler, NULL, input("IOR")); + else + BsdfNode::compile(compiler, input("Roughness"), input("IOR")); +} + +void RefractionBsdfNode::compile(OSLCompiler& compiler) +{ + compiler.parameter("distribution", distribution); + compiler.add(this, "node_refraction_bsdf"); +} + /* Velvet BSDF Closure */ VelvetBsdfNode::VelvetBsdfNode() @@ -1469,6 +1573,34 @@ void HoldoutNode::compile(OSLCompiler& compiler) compiler.add(this, "node_holdout"); } +/* Ambient Occlusion */ + +AmbientOcclusionNode::AmbientOcclusionNode() +: ShaderNode("ambient_occlusion") +{ + add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f)); + add_output("AO", SHADER_SOCKET_CLOSURE); +} + +void AmbientOcclusionNode::compile(SVMCompiler& compiler) +{ + ShaderInput *color_in = input("Color"); + + if(color_in->link) { + compiler.stack_assign(color_in); + compiler.add_node(NODE_CLOSURE_WEIGHT, color_in->stack_offset); + } + else + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value); + + compiler.add_node(NODE_CLOSURE_AMBIENT_OCCLUSION, compiler.closure_mix_weight_offset()); +} + +void AmbientOcclusionNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "node_ambient_occlusion"); +} + /* Volume Closure */ VolumeNode::VolumeNode() @@ -1566,6 +1698,14 @@ GeometryNode::GeometryNode() add_output("Backfacing", SHADER_SOCKET_FLOAT); } +void GeometryNode::attributes(AttributeRequestSet *attributes) +{ + if(!output("Tangent")->links.empty()) + attributes->add(ATTR_STD_GENERATED); + + ShaderNode::attributes(attributes); +} + void GeometryNode::compile(SVMCompiler& compiler) { ShaderOutput *out; @@ -1636,7 +1776,7 @@ void GeometryNode::compile(OSLCompiler& compiler) TextureCoordinateNode::TextureCoordinateNode() : ShaderNode("texture_coordinate") { - add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); add_output("Generated", SHADER_SOCKET_POINT); add_output("Normal", SHADER_SOCKET_NORMAL); add_output("UV", SHADER_SOCKET_POINT); @@ -1758,6 +1898,8 @@ void TextureCoordinateNode::compile(OSLCompiler& compiler) if(compiler.background) compiler.parameter("is_background", true); + + compiler.parameter("from_dupli", from_dupli); compiler.add(this, "node_texture_coordinate"); } @@ -1996,13 +2138,14 @@ void ParticleInfoNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, out->stack_offset); } - #if 0 /* XXX Quaternion data is not yet supported by Cycles */ + /* quaternion data is not yet supported by Cycles */ +#if 0 out = output("Rotation"); if(!out->links.empty()) { compiler.stack_assign(out); compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, out->stack_offset); } - #endif +#endif out = output("Size"); if(!out->links.empty()) { @@ -2184,7 +2327,7 @@ static ShaderEnum mix_type_init() enm.insert("Burn", NODE_MIX_BURN); enm.insert("Hue", NODE_MIX_HUE); enm.insert("Saturation", NODE_MIX_SAT); - enm.insert("Value", NODE_MIX_VAL ); + enm.insert("Value", NODE_MIX_VAL); enm.insert("Color", NODE_MIX_COLOR); enm.insert("Soft Light", NODE_MIX_SOFT); enm.insert("Linear Light", NODE_MIX_LINEAR); @@ -2544,7 +2687,7 @@ void LayerWeightNode::compile(SVMCompiler& compiler) void LayerWeightNode::compile(OSLCompiler& compiler) { - compiler.add(this, "node_blend_weight"); + compiler.add(this, "node_layer_weight"); } /* Output */ @@ -2555,6 +2698,7 @@ OutputNode::OutputNode() add_input("Surface", SHADER_SOCKET_CLOSURE); add_input("Volume", SHADER_SOCKET_CLOSURE); add_input("Displacement", SHADER_SOCKET_FLOAT); + add_input("Normal", SHADER_SOCKET_NORMAL); } void OutputNode::compile(SVMCompiler& compiler) @@ -2702,9 +2846,15 @@ void VectorMathNode::compile(OSLCompiler& compiler) BumpNode::BumpNode() : ShaderNode("bump") { + /* this input is used by the user, but after graph transform it is no longer + * used and moved to sampler center/x/y instead */ + add_input("Height", SHADER_SOCKET_FLOAT); + add_input("SampleCenter", SHADER_SOCKET_FLOAT); add_input("SampleX", SHADER_SOCKET_FLOAT); add_input("SampleY", SHADER_SOCKET_FLOAT); + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); + add_input("Strength", SHADER_SOCKET_FLOAT, 0.1f); add_output("Normal", SHADER_SOCKET_NORMAL); } @@ -2714,12 +2864,25 @@ void BumpNode::compile(SVMCompiler& compiler) ShaderInput *center_in = input("SampleCenter"); ShaderInput *dx_in = input("SampleX"); ShaderInput *dy_in = input("SampleY"); + ShaderInput *normal_in = input("NormalIn"); + ShaderInput *intensity_in = input("Strength"); + ShaderOutput *normal_out = output("Normal"); compiler.stack_assign(center_in); compiler.stack_assign(dx_in); compiler.stack_assign(dy_in); + compiler.stack_assign(intensity_in); + compiler.stack_assign(normal_out); - compiler.add_node(NODE_SET_BUMP, center_in->stack_offset, dx_in->stack_offset, dy_in->stack_offset); + if(normal_in->link) + compiler.stack_assign(normal_in); + + /* pack all parameters in the node */ + compiler.add_node(NODE_SET_BUMP, + normal_in->stack_offset, + compiler.encode_uchar4(center_in->stack_offset, dx_in->stack_offset, + dy_in->stack_offset, intensity_in->stack_offset), + normal_out->stack_offset); } void BumpNode::compile(OSLCompiler& compiler) @@ -2788,17 +2951,245 @@ void RGBRampNode::compile(OSLCompiler& compiler) /* NB: cycles float3 type is actually 4 floats! need to use an explicit array */ float ramp_color[RAMP_TABLE_SIZE][3]; float ramp_alpha[RAMP_TABLE_SIZE]; + for (int i = 0; i < RAMP_TABLE_SIZE; ++i) { ramp_color[i][0] = ramp[i].x; ramp_color[i][1] = ramp[i].y; ramp_color[i][2] = ramp[i].z; ramp_alpha[i] = ramp[i].w; } + compiler.parameter_color_array("ramp_color", ramp_color, RAMP_TABLE_SIZE); compiler.parameter_array("ramp_alpha", ramp_alpha, RAMP_TABLE_SIZE); compiler.add(this, "node_rgb_ramp"); } +/* Set Normal Node */ + +SetNormalNode::SetNormalNode() +: ShaderNode("set_normal") +{ + add_input("Direction", SHADER_SOCKET_VECTOR); + add_output("Normal", SHADER_SOCKET_NORMAL); +} + +void SetNormalNode::compile(SVMCompiler& compiler) +{ + ShaderInput *direction_in = input("Direction"); + ShaderOutput *normal_out = output("Normal"); + + compiler.stack_assign(direction_in); + compiler.stack_assign(normal_out); + + compiler.add_node(NODE_CLOSURE_SET_NORMAL, direction_in->stack_offset, normal_out->stack_offset); +} + +void SetNormalNode::compile(OSLCompiler& compiler) +{ + compiler.add(this, "node_set_normal"); +} + +/* OSLScriptNode */ + +OSLScriptNode::OSLScriptNode() +: ShaderNode("osl_script") +{ +} + +void OSLScriptNode::compile(SVMCompiler& compiler) +{ + /* doesn't work for SVM, obviously ... */ +} + +void OSLScriptNode::compile(OSLCompiler& compiler) +{ + if(!filepath.empty()) + compiler.add(this, filepath.c_str(), true); + else + compiler.add(this, bytecode_hash.c_str(), false); +} + +/* Normal Map */ + +static ShaderEnum normal_map_space_init() +{ + ShaderEnum enm; + + enm.insert("Tangent", NODE_NORMAL_MAP_TANGENT); + enm.insert("Object", NODE_NORMAL_MAP_OBJECT); + enm.insert("World", NODE_NORMAL_MAP_WORLD); + + return enm; +} + +ShaderEnum NormalMapNode::space_enum = normal_map_space_init(); + +NormalMapNode::NormalMapNode() +: ShaderNode("normal_map") +{ + space = ustring("Tangent"); + attribute = ustring(""); + + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Color", SHADER_SOCKET_COLOR); + + add_output("Normal", SHADER_SOCKET_NORMAL); +} + +void NormalMapNode::attributes(AttributeRequestSet *attributes) +{ + if(space == ustring("Tangent")) { + if(attribute == ustring("")) { + attributes->add(ATTR_STD_UV_TANGENT); + attributes->add(ATTR_STD_UV_TANGENT_SIGN); + } + else { + attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); + attributes->add(ustring((string(attribute.c_str()) + ".tangent_sign").c_str())); + } + } + + ShaderNode::attributes(attributes); +} + +void NormalMapNode::compile(SVMCompiler& compiler) +{ + ShaderInput *color_in = input("Color"); + ShaderInput *strength_in = input("Strength"); + ShaderOutput *normal_out = output("Normal"); + int attr = 0, attr_sign = 0; + + if(space == ustring("Tangent")) { + if(attribute == ustring("")) { + attr = compiler.attribute(ATTR_STD_UV_TANGENT); + attr_sign = compiler.attribute(ATTR_STD_UV_TANGENT_SIGN); + } + else { + attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str())); + attr_sign = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent_sign").c_str())); + } + } + + compiler.stack_assign(color_in); + compiler.stack_assign(strength_in); + compiler.stack_assign(normal_out); + + compiler.add_node(NODE_NORMAL_MAP, + compiler.encode_uchar4( + color_in->stack_offset, + strength_in->stack_offset, + normal_out->stack_offset, + space_enum[space]), + attr, attr_sign); +} + +void NormalMapNode::compile(OSLCompiler& compiler) +{ + if(space == ustring("Tangent")) { + if(attribute == ustring("")) { + compiler.parameter("attr_name", ustring("geom:tangent")); + compiler.parameter("attr_sign_name", ustring("geom:tangent_sign")); + } + else { + compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str())); + compiler.parameter("attr_sign_name", ustring((string(attribute.c_str()) + ".tangent_sign").c_str())); + } + } + + compiler.parameter("space", space); + + compiler.add(this, "node_normal_map"); +} + +/* Tangent */ + +static ShaderEnum tangent_direction_type_init() +{ + ShaderEnum enm; + + enm.insert("Radial", NODE_TANGENT_RADIAL); + enm.insert("UV Map", NODE_TANGENT_UVMAP); + + return enm; +} + +static ShaderEnum tangent_axis_init() +{ + ShaderEnum enm; + + enm.insert("X", NODE_TANGENT_AXIS_X); + enm.insert("Y", NODE_TANGENT_AXIS_Y); + enm.insert("Z", NODE_TANGENT_AXIS_Z); + + return enm; +} + +ShaderEnum TangentNode::direction_type_enum = tangent_direction_type_init(); +ShaderEnum TangentNode::axis_enum = tangent_axis_init(); + +TangentNode::TangentNode() +: ShaderNode("normal_map") +{ + direction_type = ustring("Radial"); + axis = ustring("X"); + attribute = ustring(""); + + add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true); + add_output("Tangent", SHADER_SOCKET_NORMAL); +} + +void TangentNode::attributes(AttributeRequestSet *attributes) +{ + if(direction_type == ustring("UV Map")) { + if(attribute == ustring("")) + attributes->add(ATTR_STD_UV_TANGENT); + else + attributes->add(ustring((string(attribute.c_str()) + ".tangent").c_str())); + } + else + attributes->add(ATTR_STD_GENERATED); + + ShaderNode::attributes(attributes); +} + +void TangentNode::compile(SVMCompiler& compiler) +{ + ShaderOutput *tangent_out = output("Tangent"); + int attr; + + if(direction_type == ustring("UV Map")) { + if(attribute == ustring("")) + attr = compiler.attribute(ATTR_STD_UV_TANGENT); + else + attr = compiler.attribute(ustring((string(attribute.c_str()) + ".tangent").c_str())); + } + else + attr = compiler.attribute(ATTR_STD_GENERATED); + + compiler.stack_assign(tangent_out); + + compiler.add_node(NODE_TANGENT, + compiler.encode_uchar4( + tangent_out->stack_offset, + direction_type_enum[direction_type], + axis_enum[axis]), attr); +} + +void TangentNode::compile(OSLCompiler& compiler) +{ + if(direction_type == ustring("UV Map")) { + if(attribute == ustring("")) + compiler.parameter("attr_name", ustring("geom:tangent")); + else + compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str())); + } + + compiler.parameter("direction_type", direction_type); + compiler.parameter("axis", axis); + compiler.add(this, "node_tangent"); +} + CCL_NAMESPACE_END |