diff options
Diffstat (limited to 'intern/cycles/render/nodes.cpp')
-rw-r--r-- | intern/cycles/render/nodes.cpp | 250 |
1 files changed, 209 insertions, 41 deletions
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index e7f13f3123f..cce851612db 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -82,7 +82,7 @@ Transform TextureMapping::compute_transform() mmat[1][y_mapping-1] = 1.0f; if(z_mapping != NONE) mmat[2][z_mapping-1] = 1.0f; - + float3 scale_clamped = scale; if(type == TEXTURE || type == NORMAL) { @@ -94,7 +94,7 @@ Transform TextureMapping::compute_transform() if(fabsf(scale.z) < 1e-5f) scale_clamped.z = signf(scale.z)*1e-5f; } - + Transform smat = transform_scale(scale_clamped); Transform rmat = transform_euler(rotation); Transform tmat = transform_translate(translation); @@ -137,12 +137,12 @@ bool TextureMapping::skip() return false; if(scale != make_float3(1.0f, 1.0f, 1.0f)) return false; - + if(x_mapping != X || y_mapping != Y || z_mapping != Z) return false; if(use_minmax) return false; - + return true; } @@ -520,7 +520,7 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign_if_linked(alpha_out), srgb), projection); - + tex_mapping.compile_end(compiler, vector_in, vector_offset); } else { @@ -612,7 +612,7 @@ static void sky_texture_precompute_old(SunSky *sunsky, float3 dir, float turbidi * zenith_Y/x/y is now radiance_x/y/z * perez_Y/x/y is now config_x/y/z */ - + float2 spherical = sky_spherical_coordinates(dir); float theta = spherical.x; float phi = spherical.y; @@ -676,12 +676,12 @@ static void sky_texture_precompute_new(SunSky *sunsky, float3 dir, float turbidi float2 spherical = sky_spherical_coordinates(dir); float theta = spherical.x; float phi = spherical.y; - + /* Clamp Turbidity */ - turbidity = clamp(turbidity, 0.0f, 10.0f); - + turbidity = clamp(turbidity, 0.0f, 10.0f); + /* Clamp to Horizon */ - theta = clamp(theta, 0.0f, M_PI_2_F); + theta = clamp(theta, 0.0f, M_PI_2_F); sunsky->theta = theta; sunsky->phi = phi; @@ -773,7 +773,7 @@ void SkyTextureNode::compile(OSLCompiler& compiler) sky_texture_precompute_new(&sunsky, sun_direction, turbidity, ground_albedo); else assert(false); - + compiler.parameter(this, "type"); compiler.parameter("theta", sunsky.theta); compiler.parameter("phi", sunsky.phi); @@ -913,7 +913,23 @@ NODE_DEFINE(VoronoiTextureNode) coloring_enum.insert("cells", NODE_VORONOI_CELLS); SOCKET_ENUM(coloring, "Coloring", coloring_enum, NODE_VORONOI_INTENSITY); + static NodeEnum metric; + metric.insert("distance", NODE_VORONOI_DISTANCE); + metric.insert("manhattan", NODE_VORONOI_MANHATTAN); + metric.insert("chebychev", NODE_VORONOI_CHEBYCHEV); + metric.insert("minkowski", NODE_VORONOI_MINKOWSKI); + SOCKET_ENUM(metric, "Distance Metric", metric, NODE_VORONOI_INTENSITY); + + static NodeEnum feature_enum; + feature_enum.insert("F1", NODE_VORONOI_F1); + feature_enum.insert("F2", NODE_VORONOI_F2); + feature_enum.insert("F3", NODE_VORONOI_F3); + feature_enum.insert("F4", NODE_VORONOI_F4); + feature_enum.insert("F2F1", NODE_VORONOI_F2F1); + SOCKET_ENUM(feature, "Feature", feature_enum, NODE_VORONOI_INTENSITY); + SOCKET_IN_FLOAT(scale, "Scale", 1.0f); + SOCKET_IN_FLOAT(exponent, "Exponent", 0.5f); SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); SOCKET_OUT_COLOR(color, "Color"); @@ -931,19 +947,32 @@ void VoronoiTextureNode::compile(SVMCompiler& compiler) { ShaderInput *scale_in = input("Scale"); ShaderInput *vector_in = input("Vector"); + ShaderInput *exponent_in = input("Exponent"); ShaderOutput *color_out = output("Color"); ShaderOutput *fac_out = output("Fac"); + if (vector_in->link) compiler.stack_assign(vector_in); + if (scale_in->link) compiler.stack_assign(scale_in); + if (exponent_in->link) compiler.stack_assign(exponent_in); + int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.add_node(NODE_TEX_VORONOI, - coloring, compiler.encode_uchar4( - compiler.stack_assign_if_linked(scale_in), vector_offset, + coloring, + metric, + feature + ), + compiler.encode_uchar4( + compiler.stack_assign_if_linked(scale_in), + compiler.stack_assign_if_linked(exponent_in), compiler.stack_assign(fac_out), - compiler.stack_assign(color_out)), - __float_as_int(scale)); + compiler.stack_assign(color_out) + )); + compiler.add_node( + __float_as_int(scale), + __float_as_int(exponent)); tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -953,6 +982,8 @@ void VoronoiTextureNode::compile(OSLCompiler& compiler) tex_mapping.compile(compiler); compiler.parameter(this, "coloring"); + compiler.parameter(this, "metric"); + compiler.parameter(this, "feature"); compiler.add(this, "node_voronoi_texture"); } @@ -1296,7 +1327,7 @@ void CheckerTextureNode::compile(SVMCompiler& compiler) ShaderInput *color1_in = input("Color1"); ShaderInput *color2_in = input("Color2"); ShaderInput *scale_in = input("Scale"); - + ShaderOutput *color_out = output("Color"); ShaderOutput *fac_out = output("Fac"); @@ -1371,7 +1402,7 @@ void BrickTextureNode::compile(SVMCompiler& compiler) ShaderInput *bias_in = input("Bias"); ShaderInput *brick_width_in = input("Brick Width"); ShaderInput *row_height_in = input("Row Height"); - + ShaderOutput *color_out = output("Color"); ShaderOutput *fac_out = output("Fac"); @@ -1393,7 +1424,7 @@ void BrickTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign_if_linked(color_out), compiler.stack_assign_if_linked(fac_out), compiler.stack_assign_if_linked(mortar_smooth_in))); - + compiler.add_node(compiler.encode_uchar4(offset_frequency, squash_frequency), __float_as_int(scale), __float_as_int(mortar_size), @@ -2307,7 +2338,7 @@ ToonBsdfNode::ToonBsdfNode() void ToonBsdfNode::compile(SVMCompiler& compiler) { closure = component; - + BsdfNode::compile(compiler, input("Size"), input("Smooth")); } @@ -2861,7 +2892,7 @@ void VolumeNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in)); else compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color); - + compiler.add_node(NODE_CLOSURE_VOLUME, compiler.encode_uchar4(closure, (param1)? compiler.stack_assign(param1): SVM_STACK_INVALID, @@ -3058,6 +3089,139 @@ void PrincipledVolumeNode::compile(OSLCompiler& compiler) compiler.add(this, "node_principled_volume"); } +/* Principled Hair BSDF Closure */ + +NODE_DEFINE(PrincipledHairBsdfNode) +{ + NodeType* type = NodeType::add("principled_hair_bsdf", create, NodeType::SHADER); + + /* Color parametrization specified as enum. */ + static NodeEnum parametrization_enum; + parametrization_enum.insert("Direct coloring", NODE_PRINCIPLED_HAIR_REFLECTANCE); + parametrization_enum.insert("Melanin concentration", NODE_PRINCIPLED_HAIR_PIGMENT_CONCENTRATION); + parametrization_enum.insert("Absorption coefficient", NODE_PRINCIPLED_HAIR_DIRECT_ABSORPTION); + SOCKET_ENUM(parametrization, "Parametrization", parametrization_enum, NODE_PRINCIPLED_HAIR_REFLECTANCE); + + /* Initialize sockets to their default values. */ + SOCKET_IN_COLOR(color, "Color", make_float3(0.017513f, 0.005763f, 0.002059f)); + SOCKET_IN_FLOAT(melanin, "Melanin", 0.8f); + SOCKET_IN_FLOAT(melanin_redness, "Melanin Redness", 1.0f); + SOCKET_IN_COLOR(tint, "Tint", make_float3(1.f, 1.f, 1.f)); + SOCKET_IN_VECTOR(absorption_coefficient, "Absorption Coefficient", make_float3(0.245531f, 0.52f, 1.365f), SocketType::VECTOR); + + SOCKET_IN_FLOAT(offset, "Offset", 2.f*M_PI_F/180.f); + SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f); + SOCKET_IN_FLOAT(radial_roughness, "Radial Roughness", 0.3f); + SOCKET_IN_FLOAT(coat, "Coat", 0.0f); + SOCKET_IN_FLOAT(ior, "IOR", 1.55f); + + SOCKET_IN_FLOAT(random_roughness, "Random Roughness", 0.0f); + SOCKET_IN_FLOAT(random_color, "Random Color", 0.0f); + SOCKET_IN_FLOAT(random, "Random", 0.0f); + + SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL); + SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL); + + SOCKET_OUT_CLOSURE(BSDF, "BSDF"); + + return type; +} + +PrincipledHairBsdfNode::PrincipledHairBsdfNode() +: BsdfBaseNode(node_type) +{ + closure = CLOSURE_BSDF_HAIR_PRINCIPLED_ID; +} + +/* Enable retrieving Hair Info -> Random if Random isn't linked. */ +void PrincipledHairBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) +{ + if(!input("Random")->link) { + attributes->add(ATTR_STD_CURVE_RANDOM); + } + ShaderNode::attributes(shader, attributes); +} + +/* Prepares the input data for the SVM shader. */ +void PrincipledHairBsdfNode::compile(SVMCompiler& compiler) +{ + compiler.add_node(NODE_CLOSURE_SET_WEIGHT, make_float3(1.0f, 1.0f, 1.0f)); + + ShaderInput *roughness_in = input("Roughness"); + ShaderInput *radial_roughness_in = input("Radial Roughness"); + ShaderInput *random_roughness_in = input("Random Roughness"); + ShaderInput *offset_in = input("Offset"); + ShaderInput *coat_in = input("Coat"); + ShaderInput *ior_in = input("IOR"); + ShaderInput *melanin_in = input("Melanin"); + ShaderInput *melanin_redness_in = input("Melanin Redness"); + ShaderInput *random_color_in = input("Random Color"); + + int color_ofs = compiler.stack_assign(input("Color")); + int tint_ofs = compiler.stack_assign(input("Tint")); + int absorption_coefficient_ofs = compiler.stack_assign(input("Absorption Coefficient")); + + ShaderInput *random_in = input("Random"); + int attr_random = random_in->link ? SVM_STACK_INVALID : compiler.attribute(ATTR_STD_CURVE_RANDOM); + + /* Encode all parameters into data nodes. */ + compiler.add_node(NODE_CLOSURE_BSDF, + /* Socket IDs can be packed 4 at a time into a single data packet */ + compiler.encode_uchar4(closure, + compiler.stack_assign_if_linked(roughness_in), + compiler.stack_assign_if_linked(radial_roughness_in), + compiler.closure_mix_weight_offset()), + /* The rest are stored as unsigned integers */ + __float_as_uint(roughness), + __float_as_uint(radial_roughness)); + + compiler.add_node(compiler.stack_assign_if_linked(input("Normal")), + compiler.encode_uchar4( + compiler.stack_assign_if_linked(offset_in), + compiler.stack_assign_if_linked(ior_in), + color_ofs, + parametrization), + __float_as_uint(offset), + __float_as_uint(ior)); + + compiler.add_node( + compiler.encode_uchar4( + compiler.stack_assign_if_linked(coat_in), + compiler.stack_assign_if_linked(melanin_in), + compiler.stack_assign_if_linked(melanin_redness_in), + absorption_coefficient_ofs), + __float_as_uint(coat), + __float_as_uint(melanin), + __float_as_uint(melanin_redness)); + + compiler.add_node( + compiler.encode_uchar4( + tint_ofs, + compiler.stack_assign_if_linked(random_in), + compiler.stack_assign_if_linked(random_color_in), + compiler.stack_assign_if_linked(random_roughness_in)), + __float_as_uint(random), + __float_as_uint(random_color), + __float_as_uint(random_roughness)); + + compiler.add_node( + compiler.encode_uchar4( + SVM_STACK_INVALID, + SVM_STACK_INVALID, + SVM_STACK_INVALID, + SVM_STACK_INVALID), + attr_random, + SVM_STACK_INVALID, + SVM_STACK_INVALID); +} + +/* Prepares the input data for the OSL shader. */ +void PrincipledHairBsdfNode::compile(OSLCompiler& compiler) +{ + compiler.parameter(this, "parametrization"); + compiler.add(this, "node_principled_hair_bsdf"); +} + /* Hair BSDF Closure */ NODE_DEFINE(HairBsdfNode) @@ -3155,7 +3319,7 @@ void GeometryNode::compile(SVMCompiler& compiler) geom_node = NODE_GEOMETRY_BUMP_DY; attr_node = NODE_ATTR_BUMP_DY; } - + out = output("Position"); if(!out->links.empty()) { compiler.add_node(geom_node, NODE_GEOM_P, compiler.stack_assign(out)); @@ -3284,7 +3448,7 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler) attr_node = NODE_ATTR_BUMP_DY; geom_node = NODE_GEOMETRY_BUMP_DY; } - + out = output("Generated"); if(!out->links.empty()) { if(compiler.background) { @@ -3360,7 +3524,7 @@ void TextureCoordinateNode::compile(OSLCompiler& compiler) compiler.parameter("bump_offset", "dy"); else compiler.parameter("bump_offset", "center"); - + if(compiler.background) compiler.parameter("is_background", true); if(compiler.output_type() == SHADER_TYPE_VOLUME) @@ -3522,7 +3686,7 @@ void LightPathNode::compile(SVMCompiler& compiler) if(!out->links.empty()) { compiler.add_node(NODE_LIGHT_PATH, NODE_LP_transmission, compiler.stack_assign(out)); } - + out = output("Is Volume Scatter Ray"); if(!out->links.empty()) { compiler.add_node(NODE_LIGHT_PATH, NODE_LP_volume_scatter, compiler.stack_assign(out)); @@ -3532,7 +3696,7 @@ void LightPathNode::compile(SVMCompiler& compiler) if(!out->links.empty()) { compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_length, compiler.stack_assign(out)); } - + out = output("Ray Depth"); if(!out->links.empty()) { compiler.add_node(NODE_LIGHT_PATH, NODE_LP_ray_depth, compiler.stack_assign(out)); @@ -3725,7 +3889,7 @@ void ParticleInfoNode::attributes(Shader *shader, AttributeRequestSet *attribute void ParticleInfoNode::compile(SVMCompiler& compiler) { ShaderOutput *out; - + out = output("Index"); if(!out->links.empty()) { compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, compiler.stack_assign(out)); @@ -3735,22 +3899,22 @@ void ParticleInfoNode::compile(SVMCompiler& compiler) if(!out->links.empty()) { compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_RANDOM, compiler.stack_assign(out)); } - + out = output("Age"); if(!out->links.empty()) { compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_AGE, compiler.stack_assign(out)); } - + out = output("Lifetime"); if(!out->links.empty()) { compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, compiler.stack_assign(out)); } - + out = output("Location"); if(!out->links.empty()) { compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, compiler.stack_assign(out)); } - + /* quaternion data is not yet supported by Cycles */ #if 0 out = output("Rotation"); @@ -3758,17 +3922,17 @@ void ParticleInfoNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, compiler.stack_assign(out)); } #endif - + out = output("Size"); if(!out->links.empty()) { compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, compiler.stack_assign(out)); } - + out = output("Velocity"); if(!out->links.empty()) { compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, compiler.stack_assign(out)); } - + out = output("Angular Velocity"); if(!out->links.empty()) { compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, compiler.stack_assign(out)); @@ -3821,7 +3985,7 @@ void HairInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes) void HairInfoNode::compile(SVMCompiler& compiler) { ShaderOutput *out; - + out = output("Is Strand"); if(!out->links.empty()) { compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_IS_STRAND, compiler.stack_assign(out)); @@ -4744,7 +4908,7 @@ void AttributeNode::compile(OSLCompiler& compiler) compiler.parameter("bump_offset", "dy"); else compiler.parameter("bump_offset", "center"); - + if(Attribute::name_standard(attribute.c_str()) != ATTR_STD_NONE) compiler.parameter("name", (string("geom:") + attribute.c_str()).c_str()); else @@ -5068,6 +5232,10 @@ NODE_DEFINE(MathNode) type_enum.insert("modulo", NODE_MATH_MODULO); type_enum.insert("absolute", NODE_MATH_ABSOLUTE); type_enum.insert("arctan2", NODE_MATH_ARCTAN2); + type_enum.insert("floor", NODE_MATH_FLOOR); + type_enum.insert("ceil", NODE_MATH_CEIL); + type_enum.insert("fract", NODE_MATH_FRACT); + type_enum.insert("sqrt", NODE_MATH_SQRT); SOCKET_ENUM(type, "Type", type_enum, NODE_MATH_ADD); SOCKET_BOOLEAN(use_clamp, "Use Clamp", false); @@ -5550,7 +5718,7 @@ void RGBRampNode::compile(OSLCompiler& compiler) compiler.parameter_color_array("ramp_color", ramp); compiler.parameter_array("ramp_alpha", ramp_alpha.data(), ramp_alpha.size()); compiler.parameter(this, "interpolate"); - + compiler.add(this, "node_rgb_ramp"); } @@ -5583,7 +5751,7 @@ void SetNormalNode::compile(SVMCompiler& compiler) void SetNormalNode::compile(OSLCompiler& compiler) { - compiler.add(this, "node_set_normal"); + compiler.add(this, "node_set_normal"); } /* OSLNode */ @@ -5704,7 +5872,7 @@ void NormalMapNode::attributes(Shader *shader, AttributeRequestSet *attributes) attributes->add(ATTR_STD_VERTEX_NORMAL); } - + ShaderNode::attributes(shader, attributes); } @@ -5749,7 +5917,7 @@ void NormalMapNode::compile(OSLCompiler& compiler) } compiler.parameter(this, "space"); - compiler.add(this, "node_normal_map"); + compiler.add(this, "node_normal_map"); } /* Tangent */ @@ -5794,7 +5962,7 @@ void TangentNode::attributes(Shader *shader, AttributeRequestSet *attributes) else attributes->add(ATTR_STD_GENERATED); } - + ShaderNode::attributes(shader, attributes); } @@ -5830,7 +5998,7 @@ void TangentNode::compile(OSLCompiler& compiler) compiler.parameter(this, "direction_type"); compiler.parameter(this, "axis"); - compiler.add(this, "node_tangent"); + compiler.add(this, "node_tangent"); } /* Bevel */ |