diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-01-21 02:40:42 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-02-03 14:20:26 +0300 |
commit | f9ea097a872290d20cd94504adb3172165cb770d (patch) | |
tree | 1560b65cd6b5077e8690b26bb4b2f2ff251ff358 /intern/cycles/render/nodes.cpp | |
parent | 37beac8eb823bd81b411426bfc8718639577b179 (diff) |
Cycles: add Vector Displacement node and extend Displacement node.
This adds midlevel and object/world space for displacement, and a
vector displacement node with tangent/object/world space, midlevel
and scale.
Note that tangent space vector displacement still is not exactly
compatible with maps created by other software, this will require
changes to the tangent computation.
Differential Revision: https://developer.blender.org/D1734
Diffstat (limited to 'intern/cycles/render/nodes.cpp')
-rw-r--r-- | intern/cycles/render/nodes.cpp | 107 |
1 files changed, 105 insertions, 2 deletions
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 14c0dbab9f3..acfe07bf112 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -5650,7 +5650,14 @@ NODE_DEFINE(DisplacementNode) { NodeType* type = NodeType::add("displacement", create, NodeType::SHADER); + static NodeEnum space_enum; + space_enum.insert("object", NODE_NORMAL_MAP_OBJECT); + space_enum.insert("world", NODE_NORMAL_MAP_WORLD); + + SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT); + SOCKET_IN_FLOAT(height, "Height", 0.0f); + SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.5f); SOCKET_IN_FLOAT(scale, "Scale", 1.0f); SOCKET_IN_NORMAL(normal, "Normal", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_NORMAL); @@ -5667,20 +5674,116 @@ DisplacementNode::DisplacementNode() void DisplacementNode::compile(SVMCompiler& compiler) { ShaderInput *height_in = input("Height"); + ShaderInput *midlevel_in = input("Midlevel"); ShaderInput *scale_in = input("Scale"); ShaderInput *normal_in = input("Normal"); ShaderOutput *displacement_out = output("Displacement"); compiler.add_node(NODE_DISPLACEMENT, compiler.encode_uchar4(compiler.stack_assign(height_in), + compiler.stack_assign(midlevel_in), compiler.stack_assign(scale_in), - compiler.stack_assign_if_linked(normal_in), - compiler.stack_assign(displacement_out))); + compiler.stack_assign_if_linked(normal_in)), + compiler.stack_assign(displacement_out), + space); } void DisplacementNode::compile(OSLCompiler& compiler) { + compiler.parameter(this, "space"); compiler.add(this, "node_displacement"); } +/* Vector Displacement */ + +NODE_DEFINE(VectorDisplacementNode) +{ + NodeType* type = NodeType::add("vector_displacement", create, NodeType::SHADER); + + static NodeEnum space_enum; + space_enum.insert("tangent", NODE_NORMAL_MAP_TANGENT); + space_enum.insert("object", NODE_NORMAL_MAP_OBJECT); + space_enum.insert("world", NODE_NORMAL_MAP_WORLD); + + SOCKET_ENUM(space, "Space", space_enum, NODE_NORMAL_MAP_TANGENT); + SOCKET_STRING(attribute, "Attribute", ustring("")); + + SOCKET_IN_COLOR(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f)); + SOCKET_IN_FLOAT(midlevel, "Midlevel", 0.0f); + SOCKET_IN_FLOAT(scale, "Scale", 1.0f); + + SOCKET_OUT_VECTOR(displacement, "Displacement"); + + return type; +} + +VectorDisplacementNode::VectorDisplacementNode() +: ShaderNode(node_type) +{ +} + +void VectorDisplacementNode::attributes(Shader *shader, AttributeRequestSet *attributes) +{ + if(shader->has_surface && space == NODE_NORMAL_MAP_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())); + } + + attributes->add(ATTR_STD_VERTEX_NORMAL); + } + + ShaderNode::attributes(shader, attributes); +} + +void VectorDisplacementNode::compile(SVMCompiler& compiler) +{ + ShaderInput *vector_in = input("Vector"); + ShaderInput *midlevel_in = input("Midlevel"); + ShaderInput *scale_in = input("Scale"); + ShaderOutput *displacement_out = output("Displacement"); + int attr = 0, attr_sign = 0; + + if(space == NODE_NORMAL_MAP_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.add_node(NODE_VECTOR_DISPLACEMENT, + compiler.encode_uchar4(compiler.stack_assign(vector_in), + compiler.stack_assign(midlevel_in), + compiler.stack_assign(scale_in), + compiler.stack_assign(displacement_out)), + attr, attr_sign); + + compiler.add_node(space); +} + +void VectorDisplacementNode::compile(OSLCompiler& compiler) +{ + if(space == NODE_NORMAL_MAP_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(this, "space"); + compiler.add(this, "node_vector_displacement"); +} + CCL_NAMESPACE_END |