Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMai Lavelle <mai.lavelle@gmail.com>2016-09-02 07:41:04 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-09-14 11:26:20 +0300
commit2c1201502dcac7c3febd7e09c228b05dd16b4fcd (patch)
treec5181b85d97ce3220dc9502898f12cdc32560b9d
parentb67db67b012d688b3f0b4b1d12c45e33ea2ccaab (diff)
Cycles: Fix bump mapping to use object space when used with true displacement
Bump mapping was happening in world space while displacement happens in object space, causing shading errors when displacement type was used with bump mapping. To fix this the proper transforms are added to bump nodes. This is only done for automatic bump mapping however, to avoid visual changes from other uses of bump mapping. It would be nice to do this for all bump mapping to be consistent but that will have to wait till we can break compatibility. Reviewed By: brecht Differential Revision: https://developer.blender.org/D2191
-rw-r--r--intern/cycles/kernel/shaders/node_bump.osl25
-rw-r--r--intern/cycles/kernel/svm/svm_displace.h24
-rw-r--r--intern/cycles/render/graph.cpp10
-rw-r--r--intern/cycles/render/graph.h5
-rw-r--r--intern/cycles/render/nodes.cpp5
-rw-r--r--intern/cycles/render/nodes.h1
-rw-r--r--intern/cycles/render/osl.cpp3
-rw-r--r--intern/cycles/render/svm.cpp3
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 352bed8f0f2..0332106a8a4 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -761,7 +761,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;