From eaa6479ae3482b643e6e5d553f09b1a1100b48ee Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 10 May 2013 16:57:17 +0000 Subject: [PATCH] Cycles: bump node changes to add a Distance input that controls the overall displacement distance, and an Invert option to invert the bump effect. --- intern/cycles/blender/blender_shader.cpp | 5 ++++- intern/cycles/kernel/shaders/node_bump.osl | 12 +++++++++--- intern/cycles/kernel/svm/svm_displace.h | 14 +++++++++++--- intern/cycles/render/nodes.cpp | 16 +++++++++++----- intern/cycles/render/nodes.h | 1 + source/blender/editors/space_node/drawnode.c | 8 ++++++++ .../blender/gpu/shaders/gpu_shader_material.glsl | 2 +- source/blender/makesrna/intern/rna_nodetree.c | 10 ++++++++++ source/blender/nodes/NOD_static_types.h | 2 +- .../nodes/shader/nodes/node_shader_bump.c | 3 ++- 10 files changed, 58 insertions(+), 15 deletions(-) diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 7deb826a1e1..94415514e7b 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -394,7 +394,10 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen node = new HairInfoNode(); } else if (b_node.is_a(&RNA_ShaderNodeBump)) { - node = new BumpNode(); + BL::ShaderNodeBump b_bump_node(b_node); + BumpNode *bump = new BumpNode(); + bump->invert = b_bump_node.invert(); + node = bump; } else if (b_node.is_a(&RNA_ShaderNodeScript)) { #ifdef WITH_OSL diff --git a/intern/cycles/kernel/shaders/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl index a7dd805149f..6d0ec51a9da 100644 --- a/intern/cycles/kernel/shaders/node_bump.osl +++ b/intern/cycles/kernel/shaders/node_bump.osl @@ -22,8 +22,10 @@ * Morten S. Mikkelsen, 2010 */ surface node_bump( + int invert = 0, normal NormalIn = N, - float Strength = 0.0, + float Strength = 0.1, + float Distance = 1.0, float SampleCenter = 0.0, float SampleX = 0.0, float SampleY = 0.0, @@ -42,10 +44,14 @@ surface node_bump( float absdet = fabs(det); - float strength = clamp(Strength, 0.0, 1.0); + float strength = max(Strength, 0.0); + float dist = Distance; + + if (invert) + dist *= -1.0; /* compute and output perturbed normal */ - NormalOut = normalize(absdet * NormalIn - sign(det) * surfgrad); + NormalOut = normalize(absdet * NormalIn - dist * sign(det) * surfgrad); NormalOut = normalize(strength*NormalOut + (1.0 - strength)*NormalIn); } diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h index 5d0300c5855..ee3c0c6fd21 100644 --- a/intern/cycles/kernel/svm/svm_displace.h +++ b/intern/cycles/kernel/svm/svm_displace.h @@ -24,7 +24,10 @@ __device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, { #ifdef __RAY_DIFFERENTIALS__ /* get normal input */ - float3 normal_in = stack_valid(node.y)? stack_load_float3(stack, node.y): sd->N; + uint normal_offset, distance_offset, invert; + decode_node_uchar4(node.y, &normal_offset, &distance_offset, &invert, NULL); + + float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): sd->N; /* get surface tangents from normal */ float3 Rx = cross(sd->dP.dy, normal_in); @@ -45,10 +48,15 @@ __device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, float absdet = fabsf(det); float strength = stack_load_float(stack, strength_offset); - strength = clamp(strength, 0.0f, 1.0f); + float distance = stack_load_float(stack, distance_offset); + + if(invert) + distance *= -1.0f; + + strength = max(strength, 0.0f); /* compute and output perturbed normal */ - float3 normal_out = normalize(absdet*normal_in - signf(det)*surfgrad); + float3 normal_out = normalize(absdet*normal_in - distance*signf(det)*surfgrad); normal_out = normalize(strength*normal_out + (1.0f - strength)*normal_in); stack_store_float3(stack, node.w, normal_out); #endif diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 406b5876a4b..d7ac379739d 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -3047,6 +3047,8 @@ void VectorMathNode::compile(OSLCompiler& compiler) BumpNode::BumpNode() : ShaderNode("bump") { + invert = false; + /* 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); @@ -3055,7 +3057,8 @@ BumpNode::BumpNode() add_input("SampleX", SHADER_SOCKET_FLOAT); add_input("SampleY", SHADER_SOCKET_FLOAT); add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL); - add_input("Strength", SHADER_SOCKET_FLOAT, 0.1f); + add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f); + add_input("Distance", SHADER_SOCKET_FLOAT, 0.1f); add_output("Normal", SHADER_SOCKET_NORMAL); } @@ -3066,13 +3069,15 @@ void BumpNode::compile(SVMCompiler& compiler) ShaderInput *dx_in = input("SampleX"); ShaderInput *dy_in = input("SampleY"); ShaderInput *normal_in = input("Normal"); - ShaderInput *intensity_in = input("Strength"); + ShaderInput *strength_in = input("Strength"); + ShaderInput *distance_in = input("Distance"); 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(strength_in); + compiler.stack_assign(distance_in); compiler.stack_assign(normal_out); if(normal_in->link) @@ -3080,14 +3085,15 @@ void BumpNode::compile(SVMCompiler& compiler) /* pack all parameters in the node */ compiler.add_node(NODE_SET_BUMP, - normal_in->stack_offset, + compiler.encode_uchar4(normal_in->stack_offset, distance_in->stack_offset, invert), compiler.encode_uchar4(center_in->stack_offset, dx_in->stack_offset, - dy_in->stack_offset, intensity_in->stack_offset), + dy_in->stack_offset, strength_in->stack_offset), normal_out->stack_offset); } void BumpNode::compile(OSLCompiler& compiler) { + compiler.parameter("invert", invert); compiler.add(this, "node_bump"); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 85829e00782..41fa87a3859 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -470,6 +470,7 @@ public: class BumpNode : public ShaderNode { public: SHADER_NODE_CLASS(BumpNode) + bool invert; }; class RGBCurvesNode : public ShaderNode { diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 084ec53ff7e..9ce28cc3314 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -839,6 +839,11 @@ static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), Po uiItemR(layout, ptr, "from_dupli", 0, NULL, 0); } +static void node_shader_buts_bump(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "invert", 0, NULL, 0); +} + static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRNA *ptr) { uiItemR(layout, ptr, "space", 0, "", 0); @@ -990,6 +995,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_TEX_COORD: ntype->uifunc = node_shader_buts_tex_coord; break; + case SH_NODE_BUMP: + ntype->uifunc = node_shader_buts_bump; + break; case SH_NODE_NORMAL_MAP: ntype->uifunc = node_shader_buts_normal_map; break; diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index d9f5d99f950..fd519a86fc9 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2260,7 +2260,7 @@ void node_object_info(out vec3 location, out float object_index, out float mater random = 0.0; } -void node_bump(float strength, float height, vec3 N, out vec3 result) +void node_bump(float strength, float dist, float height, vec3 N, out vec3 result) { result = N; } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index d2d3a4b0488..d05692f9abc 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3416,6 +3416,16 @@ static void def_glossy(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_sh_bump(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1); + RNA_def_property_ui_text(prop, "Invert", "Invert the bump mapping direction to push into the surface instead of out"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); +} + static void def_sh_normal_map(StructRNA *srna) { static EnumPropertyItem prop_space_items[] = { diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 4a45f98f7c9..f9868966892 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -94,7 +94,7 @@ DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LI DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" ) DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" ) DefNode( ShaderNode, SH_NODE_HAIR_INFO, 0, "HAIR_INFO", HairInfo, "Hair Info", "" ) -DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", Bump, "Bump", "" ) +DefNode( ShaderNode, SH_NODE_BUMP, def_sh_bump, "BUMP", Bump, "Bump", "" ) DefNode( ShaderNode, SH_NODE_NORMAL_MAP, def_sh_normal_map, "NORMAL_MAP", NormalMap, "Normal Map", "" ) DefNode( ShaderNode, SH_NODE_TANGENT, def_sh_tangent, "TANGENT", Tangent, "Tangent", "" ) DefNode( ShaderNode, SH_NODE_SCRIPT, def_sh_script, "SCRIPT", Script, "Script", "" ) diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c index b5b093ac7fa..2b58bd3395b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bump.c +++ b/source/blender/nodes/shader/nodes/node_shader_bump.c @@ -36,7 +36,8 @@ /* **************** BUMP ******************** */ static bNodeSocketTemplate sh_node_bump_in[] = { - { SOCK_FLOAT, 1, N_("Strength"), 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, N_("Distance"), 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, { SOCK_FLOAT, 1, N_("Height"), 1.0f, 1.0f, 1.0f, 1.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE}, { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" }