[Bf-blender-cvs] [a97bc1b] master: Fix T43755: Wireframe attribute doesn't work with displace

Sergey Sharybin noreply at git.blender.org
Sat Feb 21 13:32:08 CET 2015


Commit: a97bc1bedf6fa63cbafbc9f004f9a6c8f472ae44
Author: Sergey Sharybin
Date:   Sat Feb 21 14:49:55 2015 +0500
Branches: master
https://developer.blender.org/rBa97bc1bedf6fa63cbafbc9f004f9a6c8f472ae44

Fix T43755: Wireframe attribute doesn't work with displace

This attribute missed derivatives calculation.

Not totally sure what's the proper approach for algebraic derivative
calculation, so calculating them by definition. This isn't fastest
way to do it in this case and could be replaced with some smarter magic
in the wireframe calculation loop.

At least currently implemented approach is better than nothing.

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

M	intern/cycles/kernel/shaders/node_wireframe.osl
M	intern/cycles/kernel/svm/svm.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/kernel/svm/svm_wireframe.h
M	intern/cycles/render/nodes.cpp

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

diff --git a/intern/cycles/kernel/shaders/node_wireframe.osl b/intern/cycles/kernel/shaders/node_wireframe.osl
index 936e9bb..1ab0a65 100644
--- a/intern/cycles/kernel/shaders/node_wireframe.osl
+++ b/intern/cycles/kernel/shaders/node_wireframe.osl
@@ -18,10 +18,21 @@
 #include "oslutil.h"
 
 shader node_wireframe(
+	string bump_offset = "center",
 	int use_pixel_size = 0,
 	float Size = 0.01,
 	output float Fac = 0.0)
 {
 	Fac = wireframe("triangles", Size, use_pixel_size);
+	if (bump_offset == "dx") {
+		point dx = Dx(P);
+		P -= dx;
+		Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dx);
+	}
+	else if (bump_offset == "dy") {
+		point dy = Dy(P);
+		P -= dy;
+		Fac += (Fac - wireframe("triangles", Size, use_pixel_size)) / length(dy);
+	}
 }
 
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 6a673d3..d59c9b9 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -361,7 +361,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
 				break;
 #ifdef __EXTRA_NODES__
 			case NODE_WIREFRAME:
-				svm_node_wireframe(kg, sd, stack, node.y, node.z, node.w);
+				svm_node_wireframe(kg, sd, stack, node);
 				break;
 			case NODE_WAVELENGTH:
 				svm_node_wavelength(sd, stack, node.y, node.z);
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index a8d0da6..7130b14 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -341,6 +341,12 @@ typedef enum NodeImageProjection {
 	NODE_IMAGE_PROJ_TUBE   = 3,
 } NodeImageProjection;
 
+typedef enum NodeBumpOffset {
+	NODE_BUMP_OFFSET_CENTER,
+	NODE_BUMP_OFFSET_DX,
+	NODE_BUMP_OFFSET_DY,
+} NodeBumpOffset;
+
 typedef enum ShaderType {
 	SHADER_TYPE_SURFACE,
 	SHADER_TYPE_VOLUME,
diff --git a/intern/cycles/kernel/svm/svm_wireframe.h b/intern/cycles/kernel/svm/svm_wireframe.h
index 660e6e2..42fe3e8 100644
--- a/intern/cycles/kernel/svm/svm_wireframe.h
+++ b/intern/cycles/kernel/svm/svm_wireframe.h
@@ -34,16 +34,12 @@ CCL_NAMESPACE_BEGIN
 
 /* Wireframe Node */
 
-ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_size, uint out_fac, uint use_pixel_size)
+ccl_device float wireframe(KernelGlobals *kg,
+                           ShaderData *sd,
+                           float size,
+                           int pixel_size,
+                           float3 *P)
 {
-	/* Input Data */
-	float size = stack_load_float(stack, in_size);
-	int pixel_size = (int)use_pixel_size;
-	
-	/* Output */
-	float f = 0.0f;
-
-	/* Calculate wireframe */
 #ifdef __HAIR__
 	if (sd->prim != PRIM_NONE && sd->type & PRIMITIVE_ALL_TRIANGLE)
 #else
@@ -55,7 +51,7 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta
 
 		/* Triangles */
 		int np = 3;
-		
+
 		if(sd->type & PRIMITIVE_TRIANGLE)
 			triangle_vertices(kg, sd->prim, Co);
 		else
@@ -66,7 +62,7 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta
 			object_position_transform(kg, sd, &Co[1]);
 			object_position_transform(kg, sd, &Co[2]);
 		}
-		
+
 		if(pixel_size) {
 			// Project the derivatives of P to the viewing plane defined
 			// by I so we have a measure of how big is a pixel at this point
@@ -75,24 +71,53 @@ ccl_device void svm_node_wireframe(KernelGlobals *kg, ShaderData *sd, float *sta
 			// Take the average of both axis' length
 			pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f;
 		}
-		
+
 		// Use half the width as the neighbor face will render the
 		// other half. And take the square for fast comparison
 		pixelwidth *= 0.5f * size;
 		pixelwidth *= pixelwidth;
 		for (int i = 0; i < np; i++) {
 			int i2 = i ? i - 1 : np - 1;
-			float3 dir = sd->P - Co[i];
+			float3 dir = *P - Co[i];
 			float3 edge = Co[i] - Co[i2];
 			float3 crs = cross(edge, dir);
 			// At this point dot(crs, crs) / dot(edge, edge) is
 			// the square of area / length(edge) == square of the
 			// distance to the edge.
 			if (dot(crs, crs) < (dot(edge, edge) * pixelwidth))
-				f = 1.0f;
+				return 1.0f;
 		}
 	}
-	
+	return 0.0f;
+}
+
+ccl_device void svm_node_wireframe(KernelGlobals *kg,
+                                   ShaderData *sd,
+                                   float *stack,
+                                   uint4 node)
+{
+	uint in_size = node.y;
+	uint out_fac = node.z;
+	uint use_pixel_size, bump_offset;
+	decode_node_uchar4(node.w, &use_pixel_size, &bump_offset, NULL, NULL);
+
+	/* Input Data */
+	float size = stack_load_float(stack, in_size);
+	int pixel_size = (int)use_pixel_size;
+
+	/* Calculate wireframe */
+	float f = wireframe(kg, sd, size, pixel_size, &sd->P);
+
+	/* TODO(sergey): Think of faster way to calculate derivatives. */
+	if(bump_offset == NODE_BUMP_OFFSET_DX) {
+		float3 Px = sd->P - sd->dP.dx;
+		f += (f - wireframe(kg, sd, size, pixel_size, &Px)) / len(sd->dP.dx);
+	}
+	else if (bump_offset == NODE_BUMP_OFFSET_DY) {
+		float3 Py = sd->P - sd->dP.dy;
+		f += (f - wireframe(kg, sd, size, pixel_size, &Py)) / len(sd->dP.dy);
+	}
+
 	if (stack_valid(out_fac))
 		stack_store_float(stack, out_fac, f);
 }
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index fa6ffff..7a39811 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -3577,14 +3577,34 @@ void WireframeNode::compile(SVMCompiler& compiler)
 {
 	ShaderInput *size_in = input("Size");
 	ShaderOutput *fac_out = output("Fac");
-
+	NodeBumpOffset bump_offset = NODE_BUMP_OFFSET_CENTER;
+	if(bump == SHADER_BUMP_DX) {
+		bump_offset = NODE_BUMP_OFFSET_DX;
+	}
+	else if(bump == SHADER_BUMP_DY) {
+		bump_offset = NODE_BUMP_OFFSET_DY;
+	}
 	compiler.stack_assign(size_in);
 	compiler.stack_assign(fac_out);
-	compiler.add_node(NODE_WIREFRAME, size_in->stack_offset, fac_out->stack_offset, use_pixel_size);
+	compiler.add_node(NODE_WIREFRAME,
+	                  size_in->stack_offset,
+	                  fac_out->stack_offset,
+	                  compiler.encode_uchar4(use_pixel_size,
+	                                         bump_offset,
+	                                         0, 0));
 }
 
 void WireframeNode::compile(OSLCompiler& compiler)
 {
+	if(bump == SHADER_BUMP_DX) {
+		compiler.parameter("bump_offset", "dx");
+	}
+	else if(bump == SHADER_BUMP_DY) {
+		compiler.parameter("bump_offset", "dy");
+	}
+	else {
+		compiler.parameter("bump_offset", "center");
+	}
 	compiler.parameter("use_pixel_size", use_pixel_size);
 	compiler.add(this, "node_wireframe");
 }




More information about the Bf-blender-cvs mailing list