diff options
-rw-r--r-- | intern/cycles/kernel/shaders/node_bump.osl | 25 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_displace.h | 24 | ||||
-rw-r--r-- | intern/cycles/render/graph.cpp | 10 | ||||
-rw-r--r-- | intern/cycles/render/graph.h | 5 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/osl.cpp | 3 | ||||
-rw-r--r-- | intern/cycles/render/svm.cpp | 3 |
8 files changed, 56 insertions, 20 deletions
diff --git a/intern/cycles/kernel/shaders/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl index 9882857f2ec..7f01cf2ca91 100644 --- a/intern/cycles/kernel/shaders/node_bump.osl +++ b/intern/cycles/kernel/shaders/node_bump.osl @@ -21,6 +21,7 @@ surface node_bump( int invert = 0, + int use_object_space = 0, normal NormalIn = N, float Strength = 0.1, float Distance = 1.0, @@ -29,12 +30,20 @@ surface node_bump( float SampleY = 0.0, output normal NormalOut = N) { + point Ptmp = P; + normal Normal = NormalIn; + + if (use_object_space) { + Ptmp = transform("object", Ptmp); + Normal = normalize(transform("object", Normal)); + } + /* get surface tangents from normal */ - vector dPdx = Dx(P); - vector dPdy = Dy(P); + vector dPdx = Dx(Ptmp); + vector dPdy = Dy(Ptmp); - vector Rx = cross(dPdy, NormalIn); - vector Ry = cross(NormalIn, dPdx); + vector Rx = cross(dPdy, Normal); + vector Ry = cross(Normal, dPdx); /* compute surface gradient and determinant */ float det = dot(dPdx, Rx); @@ -49,7 +58,11 @@ surface node_bump( dist *= -1.0; /* compute and output perturbed normal */ - NormalOut = normalize(absdet * NormalIn - dist * sign(det) * surfgrad); - NormalOut = normalize(strength * NormalOut + (1.0 - strength) * NormalIn); + NormalOut = normalize(absdet * Normal - dist * sign(det) * surfgrad); + NormalOut = normalize(strength * NormalOut + (1.0 - strength) * Normal); + + if (use_object_space) { + NormalOut = normalize(transform("object", "world", NormalOut)); + } } diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h index 8d4b07c9973..12a6f9a7d18 100644 --- a/intern/cycles/kernel/svm/svm_displace.h +++ b/intern/cycles/kernel/svm/svm_displace.h @@ -22,14 +22,23 @@ ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stac { #ifdef __RAY_DIFFERENTIALS__ /* get normal input */ - uint normal_offset, distance_offset, invert; - decode_node_uchar4(node.y, &normal_offset, &distance_offset, &invert, NULL); + uint normal_offset, distance_offset, invert, use_object_space; + decode_node_uchar4(node.y, &normal_offset, &distance_offset, &invert, &use_object_space); float3 normal_in = stack_valid(normal_offset)? stack_load_float3(stack, normal_offset): ccl_fetch(sd, N); + float3 dPdx = ccl_fetch(sd, dP).dx; + float3 dPdy = ccl_fetch(sd, dP).dy; + + if(use_object_space) { + object_inverse_normal_transform(kg, sd, &normal_in); + object_inverse_dir_transform(kg, sd, &dPdx); + object_inverse_dir_transform(kg, sd, &dPdy); + } + /* get surface tangents from normal */ - float3 Rx = cross(ccl_fetch(sd, dP).dy, normal_in); - float3 Ry = cross(normal_in, ccl_fetch(sd, dP).dx); + float3 Rx = cross(dPdy, normal_in); + float3 Ry = cross(normal_in, dPdx); /* get bump values */ uint c_offset, x_offset, y_offset, strength_offset; @@ -40,7 +49,7 @@ ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stac float h_y = stack_load_float(stack, y_offset); /* compute surface gradient and determinant */ - float det = dot(ccl_fetch(sd, dP).dx, Rx); + float det = dot(dPdx, Rx); float3 surfgrad = (h_x - h_c)*Rx + (h_y - h_c)*Ry; float absdet = fabsf(det); @@ -56,6 +65,11 @@ ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stac /* compute and output perturbed normal */ float3 normal_out = normalize(absdet*normal_in - distance*signf(det)*surfgrad); normal_out = normalize(strength*normal_out + (1.0f - strength)*normal_in); + + if(use_object_space) { + object_normal_transform(kg, sd, &normal_out); + } + stack_store_float3(stack, node.w, normal_out); #endif } diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 57256ceecd3..9ee8b674412 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -312,7 +312,8 @@ void ShaderGraph::relink(ShaderNode *node, ShaderOutput *from, ShaderOutput *to) void ShaderGraph::finalize(Scene *scene, bool do_bump, bool do_osl, - bool do_simplify) + bool do_simplify, + bool bump_in_object_space) { /* before compiling, the shader graph may undergo a number of modifications. * currently we set default geometry shader inputs, and create automatic bump @@ -325,7 +326,7 @@ void ShaderGraph::finalize(Scene *scene, refine_bump_nodes(); if(do_bump) - bump_from_displacement(); + bump_from_displacement(bump_in_object_space); ShaderInput *surface_in = output()->input("Surface"); ShaderInput *volume_in = output()->input("Volume"); @@ -793,7 +794,7 @@ void ShaderGraph::refine_bump_nodes() } } -void ShaderGraph::bump_from_displacement() +void ShaderGraph::bump_from_displacement(bool use_object_space) { /* generate bump mapping automatically from displacement. bump mapping is * done using a 3-tap filter, computing the displacement at the center, @@ -842,7 +843,8 @@ void ShaderGraph::bump_from_displacement() ShaderNode *set_normal = add(new SetNormalNode()); /* add bump node and connect copied graphs to it */ - ShaderNode *bump = add(new BumpNode()); + BumpNode *bump = (BumpNode*)add(new BumpNode()); + bump->use_object_space = use_object_space; ShaderOutput *out = displacement_in->link; ShaderOutput *out_center = nodes_center[out->parent]->output(out->name()); diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index b35be48d8ca..780fdf49ca4 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -258,7 +258,8 @@ public: void finalize(Scene *scene, bool do_bump = false, bool do_osl = false, - bool do_simplify = false); + bool do_simplify = false, + bool bump_in_object_space = false); int get_num_closures(); @@ -272,7 +273,7 @@ protected: void copy_nodes(ShaderNodeSet& nodes, ShaderNodeMap& nnodemap); void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack); - void bump_from_displacement(); + void bump_from_displacement(bool use_object_space); void refine_bump_nodes(); void default_inputs(bool do_osl); void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 0304d6d95d1..df43863ea7a 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -4762,6 +4762,7 @@ NODE_DEFINE(BumpNode) NodeType* type = NodeType::add("bump", create, NodeType::SHADER); SOCKET_BOOLEAN(invert, "Invert", false); + SOCKET_BOOLEAN(use_object_space, "UseObjectSpace", 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 */ @@ -4800,7 +4801,8 @@ void BumpNode::compile(SVMCompiler& compiler) compiler.encode_uchar4( compiler.stack_assign_if_linked(normal_in), compiler.stack_assign(distance_in), - invert), + invert, + use_object_space), compiler.encode_uchar4( compiler.stack_assign(center_in), compiler.stack_assign(dx_in), @@ -4812,6 +4814,7 @@ void BumpNode::compile(SVMCompiler& compiler) void BumpNode::compile(OSLCompiler& compiler) { compiler.parameter(this, "invert"); + compiler.parameter(this, "use_object_space"); compiler.add(this, "node_bump"); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index fd349f4b7e8..13791c668ed 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -874,6 +874,7 @@ public: } bool invert; + bool use_object_space; float height; float sample_center; float sample_x; diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index f83aab47e84..18a32f7f328 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -1103,7 +1103,8 @@ void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader) shader->graph_bump->finalize(scene, true, true, - shader->has_integrator_dependency); + shader->has_integrator_dependency, + shader->displacement_method == DISPLACE_BOTH); } current_shader = shader; diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index e51758035dc..8b3affb011e 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -767,7 +767,8 @@ void SVMCompiler::compile(Scene *scene, shader->graph_bump->finalize(scene, true, false, - shader->has_integrator_dependency); + shader->has_integrator_dependency, + shader->displacement_method == DISPLACE_BOTH); } current_shader = shader; |