[Bf-blender-cvs] [65afa1b] temp-cycles-microdisplacement: Cycles: Fix bump mapping to use object space when used with true displacement

Mai Lavelle noreply at git.blender.org
Sun Sep 4 19:24:13 CEST 2016


Commit: 65afa1b7d02a90d0edf6743e61319a9e71da32cd
Author: Mai Lavelle
Date:   Fri Sep 2 00:41:04 2016 -0400
Branches: temp-cycles-microdisplacement
https://developer.blender.org/rB65afa1b7d02a90d0edf6743e61319a9e71da32cd

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.

===================================================================

M	intern/cycles/kernel/shaders/node_bump.osl
M	intern/cycles/kernel/svm/svm_displace.h
M	intern/cycles/render/graph.cpp
M	intern/cycles/render/graph.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h
M	intern/cycles/render/osl.cpp
M	intern/cycles/render/svm.cpp

===================================================================

diff --git a/intern/cycles/kernel/shaders/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl
index 9882857..7f01cf2 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 8d4b07c..12a6f9a 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 57256ce..9ee8b67 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 b35be48..780fdf4 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 0304d6d..df43863 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 b0eb239..88fe6ba 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -873,6 +873,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 f83aab4..18a32f7 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 069c3e3..20ded6f 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -760,7 +760,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;




More information about the Bf-blender-cvs mailing list