diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-02-03 18:10:01 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-02-03 18:10:01 +0300 |
commit | 1bc0cd00713a573bed76ab35b6ae0cc0e9edc307 (patch) | |
tree | a24e6f88aee2a999b187dd416bef941af6450677 | |
parent | 065a84c8d0d68edece9a407dbe97828fe22d3a6f (diff) | |
parent | db989e1f118071aae6dcd9f29d10182bd5ebed0b (diff) |
Merge branch 'master' into blender2.8
32 files changed, 512 insertions, 60 deletions
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 77e5cc8cf86..13bb0094982 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1267,13 +1267,9 @@ class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel): col.prop(cmat, "sample_as_light", text="Multiple Importance") col.prop(cmat, "use_transparent_shadow") - if context.scene.cycles.feature_set == 'EXPERIMENTAL': - col.separator() - col.label(text="Geometry:") - col.prop(cmat, "displacement_method", text="") - else: - col.separator() - col.prop(mat, "pass_index") + col.separator() + col.label(text="Geometry:") + col.prop(cmat, "displacement_method", text="") col = split.column() col.label(text="Volume:") @@ -1283,9 +1279,8 @@ class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel): col.prop(cmat, "volume_interpolation", text="") col.prop(cmat, "homogeneous_volume", text="Homogeneous") - if context.scene.cycles.feature_set == 'EXPERIMENTAL': - col.separator() - col.prop(mat, "pass_index") + col.separator() + col.prop(mat, "pass_index") class CYCLES_MATERIAL_PT_viewport(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index ec334c71555..12f1cec4ac9 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -119,6 +119,7 @@ def displacement_node_insert(material, nodetree, traversed): node.location[0] = 0.5 * (from_node.location[0] + to_node.location[0]); node.location[1] = 0.5 * (from_node.location[1] + to_node.location[1]); node.inputs['Scale'].default_value = 0.1 + node.inputs['Midlevel'].default_value = 0.0 nodetree.links.new(from_socket, node.inputs['Height']) nodetree.links.new(node.outputs['Displacement'], to_socket) @@ -129,6 +130,11 @@ def displacement_nodes_insert(): if check_is_new_shading_material(material): displacement_node_insert(material, material.node_tree, traversed) +def displacement_node_space(node): + if node.bl_idname == 'ShaderNodeDisplacement': + if node.space != 'WORLD': + node.space = 'OBJECT' + def mapping_node_order_flip(node): """ @@ -366,3 +372,5 @@ def do_versions(self): cmat = mat.cycles if not cmat.is_property_set("displacement_method"): cmat.displacement_method = 'BUMP' + + foreach_cycles_node(displacement_node_space) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index adffb4ea004..df1b1a4ca10 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -97,8 +97,11 @@ struct MikkUserData { if(layer_name == NULL) { Attribute *attr_orco = attributes.find(ATTR_STD_GENERATED); - orco = attr_orco->data_float3(); - mesh_texture_space(*(BL::Mesh*)&b_mesh, orco_loc, orco_size); + + if(attr_orco) { + orco = attr_orco->data_float3(); + mesh_texture_space(*(BL::Mesh*)&b_mesh, orco_loc, orco_size); + } } else { Attribute *attr_uv = attributes.find(ustring(layer_name)); diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 8b8242ab7da..d4c34d52011 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -867,7 +867,17 @@ static ShaderNode *add_node(Scene *scene, node = bevel; } else if(b_node.is_a(&RNA_ShaderNodeDisplacement)) { - node = new DisplacementNode(); + BL::ShaderNodeDisplacement b_disp_node(b_node); + DisplacementNode *disp = new DisplacementNode(); + disp->space = (NodeNormalMapSpace)b_disp_node.space(); + node = disp; + } + else if(b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) { + BL::ShaderNodeVectorDisplacement b_disp_node(b_node); + VectorDisplacementNode *disp = new VectorDisplacementNode(); + disp->space = (NodeNormalMapSpace)b_disp_node.space(); + disp->attribute = ""; + node = disp; } if(node) { @@ -1235,7 +1245,7 @@ void BlenderSync::sync_materials(bool update_all) shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume"); shader->volume_sampling_method = get_volume_sampling(cmat); shader->volume_interpolation_method = get_volume_interpolation(cmat); - shader->displacement_method = (experimental) ? get_displacement_method(cmat) : DISPLACE_BUMP; + shader->displacement_method = get_displacement_method(cmat); shader->set_graph(graph); diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 5f10bdf2041..8f7bc7996a4 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -408,7 +408,7 @@ if(WITH_CYCLES_CUDA_BINARIES) endmacro() foreach(arch ${CYCLES_CUDA_BINARIES_ARCH}) - if(CUDA_VERSION MATCHES "90" AND ${arch} MATCHES "sm_2.") + if(CUDA_VERSION GREATER "89" AND ${arch} MATCHES "sm_2.") message(STATUS "CUDA binaries for ${arch} disabled, not supported by CUDA 9.") else() # Compile regular kernel diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt index fb983a44579..5e8e98773d9 100644 --- a/intern/cycles/kernel/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/shaders/CMakeLists.txt @@ -24,6 +24,7 @@ set(SRC_OSL node_convert_from_vector.osl node_diffuse_bsdf.osl node_displacement.osl + node_vector_displacement.osl node_emission.osl node_environment_texture.osl node_fresnel.osl diff --git a/intern/cycles/kernel/shaders/node_displacement.osl b/intern/cycles/kernel/shaders/node_displacement.osl index fb81533c778..89f35841527 100644 --- a/intern/cycles/kernel/shaders/node_displacement.osl +++ b/intern/cycles/kernel/shaders/node_displacement.osl @@ -17,13 +17,22 @@ #include "stdosl.h" shader node_displacement( + string space = "object", float Height = 0.0, + float Midlevel = 0.5, float Scale = 1.0, normal Normal = N, output vector Displacement = vector(0.0, 0.0, 0.0)) { - Displacement = normalize(transform("object", Normal)); - Displacement *= Height * Scale; - Displacement = transform("object", "world", Displacement); + Displacement = Normal; + if(space == "object") { + Displacement = transform("object", Displacement); + } + + Displacement = normalize(Displacement) * (Height - Midlevel) * Scale; + + if(space == "object") { + Displacement = transform("object", "world", Displacement); + } } diff --git a/intern/cycles/kernel/shaders/node_vector_displacement.osl b/intern/cycles/kernel/shaders/node_vector_displacement.osl new file mode 100644 index 00000000000..b19bc228e37 --- /dev/null +++ b/intern/cycles/kernel/shaders/node_vector_displacement.osl @@ -0,0 +1,60 @@ +/* + * Copyright 2011-2013 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdosl.h" + +shader node_vector_displacement( + color Vector = color(0.0, 0.0, 0.0), + float Midlevel = 0.0, + float Scale = 1.0, + string space = "tangent", + string attr_name = "geom:tangent", + string attr_sign_name = "geom:tangent_sign", + output vector Displacement = vector(0.0, 0.0, 0.0)) +{ + vector offset = (Vector - vector(Midlevel)) * Scale; + + if(space == "tangent") { + /* Tangent space. */ + vector N_object = normalize(transform("world", "object", N)); + + vector T_object; + if(getattribute(attr_name, T_object)) { + T_object = normalize(T_object); + } + else { + T_object = normalize(dPdu); + } + + vector B_object = normalize(cross(N_object, T_object)); + float tangent_sign; + if(getattribute(attr_sign_name, tangent_sign)) { + B_object *= tangent_sign; + } + + Displacement = T_object*offset[0] + N_object*offset[1] + B_object*offset[2]; + } + else { + /* Object or world space. */ + Displacement = offset; + } + + if(space != "world") { + /* Tangent or object space. */ + Displacement = transform("object", "world", Displacement); + } +} + diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index cbc603d4645..a8f99d23b7d 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -270,6 +270,9 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a case NODE_DISPLACEMENT: svm_node_displacement(kg, sd, stack, node); break; + case NODE_VECTOR_DISPLACEMENT: + svm_node_vector_displacement(kg, sd, stack, node, &offset); + break; # endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */ # ifdef __TEXTURES__ case NODE_TEX_IMAGE: diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 7fc96f7e47f..578434792e4 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -333,6 +333,8 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * } bsdf->N = N; + bsdf->T = make_float3(0.0f, 0.0f, 0.0f); + bsdf->extra = NULL; if(distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) transmission_roughness = 1.0f - (1.0f - refl_roughness) * (1.0f - transmission_roughness); diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h index 3066a364684..b9fd5bbf84d 100644 --- a/intern/cycles/kernel/svm/svm_displace.h +++ b/intern/cycles/kernel/svm/svm_displace.h @@ -89,17 +89,72 @@ ccl_device void svm_node_set_displacement(KernelGlobals *kg, ShaderData *sd, flo ccl_device void svm_node_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - uint height_offset, scale_offset, normal_offset, displacement_offset; - decode_node_uchar4(node.y, &height_offset, &scale_offset, &normal_offset, &displacement_offset); + uint height_offset, midlevel_offset, scale_offset, normal_offset; + decode_node_uchar4(node.y, &height_offset, &midlevel_offset, &scale_offset, &normal_offset); float height = stack_load_float(stack, height_offset); + float midlevel = stack_load_float(stack, midlevel_offset); float scale = stack_load_float(stack, scale_offset); float3 normal = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N; + uint space = node.w; float3 dP = normal; - object_inverse_normal_transform(kg, sd, &dP); - dP *= height * scale; - object_dir_transform(kg, sd, &dP); + + if(space == NODE_NORMAL_MAP_OBJECT) { + /* Object space. */ + object_inverse_normal_transform(kg, sd, &dP); + dP *= (height - midlevel) * scale; + object_dir_transform(kg, sd, &dP); + } + else { + /* World space. */ + dP *= (height - midlevel) * scale; + } + + stack_store_float3(stack, node.z, dP); +} + +ccl_device void svm_node_vector_displacement(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) +{ + uint4 data_node = read_node(kg, offset); + uint space = data_node.x; + + uint vector_offset, midlevel_offset,scale_offset, displacement_offset; + decode_node_uchar4(node.y, &vector_offset, &midlevel_offset, &scale_offset, &displacement_offset); + + float3 vector = stack_load_float3(stack, vector_offset); + float midlevel = stack_load_float(stack, midlevel_offset); + float scale = stack_load_float(stack, scale_offset); + float3 dP = (vector - make_float3(midlevel, midlevel, midlevel)) * scale; + + if(space == NODE_NORMAL_MAP_TANGENT) { + /* Tangent space. */ + float3 normal = sd->N; + object_inverse_normal_transform(kg, sd, &normal); + + const AttributeDescriptor attr = find_attribute(kg, sd, node.z); + float3 tangent; + if(attr.offset != ATTR_STD_NOT_FOUND) { + tangent = primitive_attribute_float3(kg, sd, attr, NULL, NULL); + } + else { + tangent = normalize(sd->dPdu); + } + + float3 bitangent = normalize(cross(normal, tangent));; + const AttributeDescriptor attr_sign = find_attribute(kg, sd, node.w); + if(attr_sign.offset != ATTR_STD_NOT_FOUND) { + float sign = primitive_attribute_float(kg, sd, attr_sign, NULL, NULL); + bitangent *= sign; + } + + dP = tangent*dP.x + normal*dP.y + bitangent*dP.z; + } + + if(space != NODE_NORMAL_MAP_WORLD) { + /* Tangent or object space. */ + object_dir_transform(kg, sd, &dP); + } stack_store_float3(stack, displacement_offset, dP); } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 00c7752da8c..6ff04a65462 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -134,6 +134,7 @@ typedef enum ShaderNodeType { NODE_LEAVE_BUMP_EVAL, NODE_BEVEL, NODE_DISPLACEMENT, + NODE_VECTOR_DISPLACEMENT, } ShaderNodeType; typedef enum NodeAttributeType { 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__ */ diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 51b7f76b9d5..a1ebb26eba3 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -625,7 +625,7 @@ void ShaderManager::get_requested_features(Scene *scene, ShaderNode *output_node = shader->graph->output(); if(output_node->input("Displacement")->link != NULL) { requested_features->nodes_features |= NODE_FEATURE_BUMP; - if(shader->displacement_method == DISPLACE_BOTH && requested_features->experimental) { + if(shader->displacement_method == DISPLACE_BOTH) { requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE; } } diff --git a/release/datafiles/locale b/release/datafiles/locale -Subproject cd65bc3277eda27e1c0b9f20a25928f6586d89a +Subproject c93ed11a47b3016cf59711ec16de2e2e94c30e9 diff --git a/release/scripts/addons b/release/scripts/addons -Subproject f5536e5e49c34dfc0a7b8990257cd393339e23c +Subproject 371960484a38fc64e0a2635170a41a0d8ab2f6b diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib -Subproject 310578043dec1aae382eb6a447ae1d103792d7e +Subproject a8515cfdfe9a98127b592f36fcbe51b7e23b969 diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 7a8e51d5590..dc8462f1af1 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -301,6 +301,7 @@ shader_node_categories = [ NodeItem("ShaderNodeMapping"), NodeItem("ShaderNodeBump"), NodeItem("ShaderNodeDisplacement"), + NodeItem("ShaderNodeVectorDisplacement"), NodeItem("ShaderNodeNormalMap"), NodeItem("ShaderNodeNormal"), NodeItem("ShaderNodeVectorCurve"), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 4e30cb076d4..770b2b4a185 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -801,6 +801,7 @@ struct ShadeResult; #define SH_NODE_EEVEE_SPECULAR 195 #define SH_NODE_BEVEL 197 #define SH_NODE_DISPLACEMENT 198 +#define SH_NODE_VECTOR_DISPLACEMENT 199 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index a5c3e6e4a43..7ed76d18958 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -3590,6 +3590,7 @@ static void registerShaderNodes(void) register_node_type_sh_attribute(); register_node_type_sh_bevel(); register_node_type_sh_displacement(); + register_node_type_sh_vector_displacement(); register_node_type_sh_geometry(); register_node_type_sh_light_path(); register_node_type_sh_light_falloff(); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 1bee2716e65..ead0e848716 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -986,7 +986,7 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN { uiItemR(layout, ptr, "space", 0, "", 0); - if (RNA_enum_get(ptr, "space") == SHD_NORMAL_MAP_TANGENT) { + if (RNA_enum_get(ptr, "space") == SHD_SPACE_TANGENT) { PointerRNA obptr = CTX_data_pointer_get(C, "active_object"); if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) { @@ -998,6 +998,11 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN } } +static void node_shader_buts_displacement(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "space", 0, "", 0); +} + static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA *ptr) { uiLayout *split, *row; @@ -1189,6 +1194,10 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_NORMAL_MAP: ntype->draw_buttons = node_shader_buts_normal_map; break; + case SH_NODE_DISPLACEMENT: + case SH_NODE_VECTOR_DISPLACEMENT: + ntype->draw_buttons = node_shader_buts_displacement; + break; case SH_NODE_TANGENT: ntype->draw_buttons = node_shader_buts_tangent; break; diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index ea5e1c4eb47..667972fc429 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -4148,9 +4148,38 @@ void node_bevel(float radius, vec3 N, out vec3 result) result = N; } -void node_displacement(float height, float dist, vec3 N, out vec3 result) +void node_displacement_object(float height, float midlevel, float scale, vec3 N, mat4 obmat, out vec3 result) { - result = height * dist * N; + N = (vec4(N, 0.0) * obmat).xyz; + result = (height - midlevel) * scale * normalize(N); + result = (obmat * vec4(result, 0.0)).xyz; +} + +void node_displacement_world(float height, float midlevel, float scale, vec3 N, out vec3 result) +{ + result = (height - midlevel) * scale * normalize(N); +} + +void node_vector_displacement_tangent(vec4 vector, float midlevel, float scale, vec4 tangent, vec3 normal, mat4 obmat, mat4 viewmat, out vec3 result) +{ + vec3 N_object = normalize(((vec4(normal, 0.0) * viewmat) * obmat).xyz); + vec3 T_object = normalize(((vec4(tangent.xyz, 0.0) * viewmat) * obmat).xyz); + vec3 B_object = tangent.w * normalize(cross(N_object, T_object)); + + vec3 offset = (vector.xyz - vec3(midlevel)) * scale; + result = offset.x * T_object + offset.y * N_object + offset.z * B_object; + result = (obmat * vec4(result, 0.0)).xyz; +} + +void node_vector_displacement_object(vec4 vector, float midlevel, float scale, mat4 obmat, out vec3 result) +{ + result = (vector.xyz - vec3(midlevel)) * scale; + result = (obmat * vec4(result, 0.0)).xyz; +} + +void node_vector_displacement_world(vec4 vector, float midlevel, float scale, out vec3 result) +{ + result = (vector.xyz - vec3(midlevel)) * scale; } /* output */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 0bd36244ffb..bddbf63d8b1 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1032,12 +1032,12 @@ typedef struct NodeSunBeams { #define SHD_TANGENT_AXIS_Y 1 #define SHD_TANGENT_AXIS_Z 2 -/* normal map space */ -#define SHD_NORMAL_MAP_TANGENT 0 -#define SHD_NORMAL_MAP_OBJECT 1 -#define SHD_NORMAL_MAP_WORLD 2 -#define SHD_NORMAL_MAP_BLENDER_OBJECT 3 -#define SHD_NORMAL_MAP_BLENDER_WORLD 4 +/* normal map, displacement space */ +#define SHD_SPACE_TANGENT 0 +#define SHD_SPACE_OBJECT 1 +#define SHD_SPACE_WORLD 2 +#define SHD_SPACE_BLENDER_OBJECT 3 +#define SHD_SPACE_BLENDER_WORLD 4 /* math node clamp */ #define SHD_MATH_CLAMP 1 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 2b2c6998eb4..59570c10ebd 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -4350,11 +4350,11 @@ static void def_sh_uvalongstroke(StructRNA *srna) static void def_sh_normal_map(StructRNA *srna) { static const EnumPropertyItem prop_space_items[] = { - {SHD_NORMAL_MAP_TANGENT, "TANGENT", 0, "Tangent Space", "Tangent space normal mapping"}, - {SHD_NORMAL_MAP_OBJECT, "OBJECT", 0, "Object Space", "Object space normal mapping"}, - {SHD_NORMAL_MAP_WORLD, "WORLD", 0, "World Space", "World space normal mapping"}, - {SHD_NORMAL_MAP_BLENDER_OBJECT, "BLENDER_OBJECT", 0, "Blender Object Space", "Object space normal mapping, compatible with Blender render baking"}, - {SHD_NORMAL_MAP_BLENDER_WORLD, "BLENDER_WORLD", 0, "Blender World Space", "World space normal mapping, compatible with Blender render baking"}, + {SHD_SPACE_TANGENT, "TANGENT", 0, "Tangent Space", "Tangent space normal mapping"}, + {SHD_SPACE_OBJECT, "OBJECT", 0, "Object Space", "Object space normal mapping"}, + {SHD_SPACE_WORLD, "WORLD", 0, "World Space", "World space normal mapping"}, + {SHD_SPACE_BLENDER_OBJECT, "BLENDER_OBJECT", 0, "Blender Object Space", "Object space normal mapping, compatible with Blender render baking"}, + {SHD_SPACE_BLENDER_WORLD, "BLENDER_WORLD", 0, "Blender World Space", "World space normal mapping, compatible with Blender render baking"}, {0, NULL, 0, NULL, NULL} }; @@ -4374,6 +4374,45 @@ static void def_sh_normal_map(StructRNA *srna) RNA_def_struct_sdna_from(srna, "bNode", NULL); } +static void def_sh_displacement(StructRNA *srna) +{ + static const EnumPropertyItem prop_space_items[] = { + {SHD_SPACE_OBJECT, "OBJECT", 0, "Object Space", "Displacement is in object space, affected by object scale"}, + {SHD_SPACE_WORLD, "WORLD", 0, "World Space", "Displacement is in world space, not affected by object scale"}, + {0, NULL, 0, NULL, NULL} + }; + + PropertyRNA *prop; + + prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, prop_space_items); + RNA_def_property_ui_text(prop, "Space", "Space of the input height"); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "bNode", NULL); +} + +static void def_sh_vector_displacement(StructRNA *srna) +{ + static const EnumPropertyItem prop_space_items[] = { + {SHD_SPACE_TANGENT, "TANGENT", 0, "Tangent Space", "Tagent space vector displacement mapping"}, + {SHD_SPACE_OBJECT, "OBJECT", 0, "Object Space", "Object space vector displacement mapping"}, + {SHD_SPACE_WORLD, "WORLD", 0, "World Space", "World space vector displacement mapping"}, + {0, NULL, 0, NULL, NULL} + }; + + PropertyRNA *prop; + + prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, prop_space_items); + RNA_def_property_ui_text(prop, "Space", "Space of the input height"); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "bNode", NULL); +} + static void def_sh_tangent(StructRNA *srna) { static const EnumPropertyItem prop_direction_type_items[] = { diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index c83daa185a8..4fefad3ffdf 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -195,6 +195,7 @@ set(SRC shader/nodes/node_shader_tangent.c shader/nodes/node_shader_bevel.c shader/nodes/node_shader_displacement.c + shader/nodes/node_shader_vector_displacement.c shader/nodes/node_shader_tex_brick.c shader/nodes/node_shader_tex_checker.c shader/nodes/node_shader_tex_coord.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index cbdfd8d3dbf..bb9f9881e33 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -80,6 +80,7 @@ void register_node_type_sh_tex_pointdensity(void); void register_node_type_sh_attribute(void); void register_node_type_sh_bevel(void); void register_node_type_sh_displacement(void); +void register_node_type_sh_vector_displacement(void); void register_node_type_sh_geometry(void); void register_node_type_sh_light_path(void); void register_node_type_sh_light_falloff(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index e2c1fae1bde..394e141647e 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -128,7 +128,8 @@ DefNode( ShaderNode, SH_NODE_UVALONGSTROKE, def_sh_uvalongstroke, "UV DefNode( ShaderNode, SH_NODE_SEPXYZ, 0, "SEPXYZ", SeparateXYZ, "Separate XYZ", "" ) DefNode( ShaderNode, SH_NODE_COMBXYZ, 0, "COMBXYZ", CombineXYZ, "Combine XYZ", "" ) DefNode( ShaderNode, SH_NODE_BEVEL, def_sh_bevel, "BEVEL", Bevel, "Bevel", "" ) -DefNode( ShaderNode, SH_NODE_DISPLACEMENT, 0, "DISPLACEMENT", Displacement, "Displacement", "" ) +DefNode( ShaderNode, SH_NODE_DISPLACEMENT, def_sh_displacement, "DISPLACEMENT", Displacement, "Displacement", "" ) +DefNode( ShaderNode, SH_NODE_VECTOR_DISPLACEMENT,def_sh_vector_displacement,"VECTOR_DISPLACEMENT",VectorDisplacement,"Vector Displacement","" ) DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" ) DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" ) diff --git a/source/blender/nodes/shader/nodes/node_shader_displacement.c b/source/blender/nodes/shader/nodes/node_shader_displacement.c index d5c191b3966..25aee34f0ab 100644 --- a/source/blender/nodes/shader/nodes/node_shader_displacement.c +++ b/source/blender/nodes/shader/nodes/node_shader_displacement.c @@ -31,6 +31,7 @@ static bNodeSocketTemplate sh_node_displacement_in[] = { { SOCK_FLOAT, 0, N_("Height"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 0, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_FLOAT, 0, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } @@ -41,13 +42,30 @@ static bNodeSocketTemplate sh_node_displacement_out[] = { { -1, 0, "" } }; +static void node_shader_init_displacement(bNodeTree *UNUSED(ntree), bNode *node) +{ + node->custom1 = SHD_SPACE_OBJECT; /* space */ + + /* Set default value here for backwards compatibility. */ + for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) { + if (STREQ(sock->name, "Midlevel")) { + ((bNodeSocketValueFloat *)sock->default_value)->value = 0.5f; + } + } +} + static int gpu_shader_displacement(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { - if (!in[2].link) { - GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[2].link); + if (!in[3].link) { + GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &in[3].link); } - return GPU_stack_link(mat, node, "node_displacement", in, out); + if(node->custom1 == SHD_SPACE_OBJECT) { + return GPU_stack_link(mat, node, "node_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); + } + else { + return GPU_stack_link(mat, node, "node_displacement_world", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); + } } /* node type definition */ @@ -59,6 +77,7 @@ void register_node_type_sh_displacement(void) node_type_compatibility(&ntype, NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_displacement_in, sh_node_displacement_out); node_type_storage(&ntype, "", NULL, NULL); + node_type_init(&ntype, node_shader_init_displacement); node_type_gpu(&ntype, gpu_shader_displacement); nodeRegisterType(&ntype); diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c index 36d7522e3e6..7584b5eba4d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c @@ -68,7 +68,7 @@ static void node_shader_exec_normal_map( float *N = shi->nmapnorm; int uv_index = 0; switch (nm->space) { - case SHD_NORMAL_MAP_TANGENT: + case SHD_SPACE_TANGENT: if (nm->uv_map[0]) { /* find uv map by name */ for (int i = 0; i < shi->totuv; i++) { @@ -96,8 +96,8 @@ static void node_shader_exec_normal_map( } break; - case SHD_NORMAL_MAP_OBJECT: - case SHD_NORMAL_MAP_BLENDER_OBJECT: + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: if (shi->use_world_space_shading) { mul_mat3_m4_v3((float (*)[4])RE_object_instance_get_matrix(shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB), vecIn); mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N); @@ -107,8 +107,8 @@ static void node_shader_exec_normal_map( interp_v3_v3v3(out[0]->vec, N, vecIn, strength); break; - case SHD_NORMAL_MAP_WORLD: - case SHD_NORMAL_MAP_BLENDER_WORLD: + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: if (shi->use_world_space_shading) mul_mat3_m4_v3((float (*)[4])RE_render_current_get_matrix(RE_VIEWINV_MATRIX), N); else @@ -150,10 +150,10 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U /* ******* CYCLES or BLENDER INTERNAL with world space shading flag ******* */ const char *color_to_normal_fnc_name = "color_to_normal_new_shading"; - if (nm->space == SHD_NORMAL_MAP_BLENDER_OBJECT || nm->space == SHD_NORMAL_MAP_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat)) + if (nm->space == SHD_SPACE_BLENDER_OBJECT || nm->space == SHD_SPACE_BLENDER_WORLD || !GPU_material_use_new_shading_nodes(mat)) color_to_normal_fnc_name = "color_to_blender_normal_new_shading"; switch (nm->space) { - case SHD_NORMAL_MAP_TANGENT: + case SHD_SPACE_TANGENT: GPU_link(mat, "color_to_normal_new_shading", realnorm, &realnorm); GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm); GPU_link(mat, "vec_math_mix", strength, realnorm, GPU_builtin(GPU_VIEW_NORMAL), &out[0].link); @@ -161,14 +161,14 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U GPU_link(mat, "direction_transform_m4v3", out[0].link, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &out[0].link); GPU_link(mat, "vect_normalize", out[0].link, &out[0].link); return true; - case SHD_NORMAL_MAP_OBJECT: - case SHD_NORMAL_MAP_BLENDER_OBJECT: + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_OBJECT_MATRIX), &realnorm); break; - case SHD_NORMAL_MAP_WORLD: - case SHD_NORMAL_MAP_BLENDER_WORLD: + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: GPU_link(mat, "direction_transform_m4v3", negnorm, GPU_builtin(GPU_INVERSE_VIEW_MATRIX), &negnorm); GPU_link(mat, color_to_normal_fnc_name, realnorm, &realnorm); break; @@ -184,15 +184,15 @@ static int gpu_shader_normal_map(GPUMaterial *mat, bNode *node, bNodeExecData *U GPU_link(mat, "vec_math_negate", negnorm, &negnorm); switch (nm->space) { - case SHD_NORMAL_MAP_TANGENT: + case SHD_SPACE_TANGENT: GPU_link(mat, "node_normal_map", GPU_attribute(CD_TANGENT, nm->uv_map), negnorm, realnorm, &realnorm); break; - case SHD_NORMAL_MAP_OBJECT: - case SHD_NORMAL_MAP_BLENDER_OBJECT: + case SHD_SPACE_OBJECT: + case SHD_SPACE_BLENDER_OBJECT: GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_LOC_TO_VIEW_MATRIX), &realnorm); break; - case SHD_NORMAL_MAP_WORLD: - case SHD_NORMAL_MAP_BLENDER_WORLD: + case SHD_SPACE_WORLD: + case SHD_SPACE_BLENDER_WORLD: GPU_link(mat, "direction_transform_m4v3", realnorm, GPU_builtin(GPU_VIEW_MATRIX), &realnorm); break; } diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c new file mode 100644 index 00000000000..c864a606812 --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c @@ -0,0 +1,83 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * 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. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "../node_shader_util.h" + +/* **************** OUTPUT ******************** */ + +static bNodeSocketTemplate sh_node_vector_displacement_in[] = { + { SOCK_RGBA, 0, N_("Vector"), 0.00f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_FLOAT, 0, N_("Midlevel"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { SOCK_FLOAT, 0, N_("Scale"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_vector_displacement_out[] = { + { SOCK_VECTOR, 0, N_("Displacement"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_init_vector_displacement(bNodeTree *UNUSED(ntree), bNode *node) +{ + node->custom1 = SHD_SPACE_TANGENT; /* space */ +} + +static int gpu_shader_vector_displacement(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) +{ + if(node->custom1 == SHD_SPACE_TANGENT) { + return GPU_stack_link(mat, + node, + "node_vector_displacement_tangent", + in, + out, + GPU_attribute(CD_TANGENT, ""), + GPU_builtin(GPU_VIEW_NORMAL), + GPU_builtin(GPU_OBJECT_MATRIX), + GPU_builtin(GPU_VIEW_MATRIX)); + } + else if(node->custom1 == SHD_SPACE_OBJECT) { + return GPU_stack_link(mat, node, "node_vector_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX)); + } + else { + return GPU_stack_link(mat, node, "node_vector_displacement_world", in, out); + } +} + +/* node type definition */ +void register_node_type_sh_vector_displacement(void) +{ + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_VECTOR_DISPLACEMENT, "Vector Displacement", NODE_CLASS_OP_VECTOR, 0); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_vector_displacement_in, sh_node_vector_displacement_out); + node_type_storage(&ntype, "", NULL, NULL); + node_type_init(&ntype, node_shader_init_vector_displacement); + node_type_gpu(&ntype, gpu_shader_vector_displacement); + + nodeRegisterType(&ntype); +} diff --git a/source/tools b/source/tools -Subproject ccf20e08702ee6424edbda01544bb9f8bc386de +Subproject b11375e89061303401376f7aeae42ac2fd64692 |