From f9ea097a872290d20cd94504adb3172165cb770d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 21 Jan 2018 00:40:42 +0100 Subject: 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 --- intern/cycles/render/nodes.cpp | 107 ++++++++++++++++++++++++++++++++++++++++- intern/cycles/render/nodes.h | 17 +++++++ 2 files changed, 122 insertions(+), 2 deletions(-) (limited to 'intern/cycles/render') 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 diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 578451cbcfa..a00b48ca5bc 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -1034,11 +1034,28 @@ public: return NODE_FEATURE_BUMP; } + NodeNormalMapSpace space; float height; + float midlevel; float scale; float3 normal; }; +class VectorDisplacementNode : public ShaderNode { +public: + SHADER_NODE_CLASS(VectorDisplacementNode) + void attributes(Shader *shader, AttributeRequestSet *attributes); + virtual int get_feature() { + return NODE_FEATURE_BUMP; + } + + NodeNormalMapSpace space; + ustring attribute; + float3 vector; + float midlevel; + float scale; +}; + CCL_NAMESPACE_END #endif /* __NODES_H__ */ -- cgit v1.2.3