[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51258] trunk/blender: Cycles: Anisotropic BSDF enabled, with tangents now computed from the active UV map.

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Oct 10 15:02:20 CEST 2012


Revision: 51258
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51258
Author:   blendix
Date:     2012-10-10 13:02:20 +0000 (Wed, 10 Oct 2012)
Log Message:
-----------
Cycles: Anisotropic BSDF enabled, with tangents now computed from the active UV map.
It's using the Ward BSDF currently, which has some energy loss so might be a bit
dark. More/better BSDF options can be implemented later.

Patch by Mike Farnsworth, some modifications by me. Currently it's not possible yet
to set a custom tangent, that will follow as part of per-bsdf normals patch.

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/blender_mesh.cpp
    trunk/blender/intern/cycles/blender/blender_shader.cpp
    trunk/blender/intern/cycles/kernel/kernel_montecarlo.h
    trunk/blender/intern/cycles/kernel/kernel_shader.h
    trunk/blender/intern/cycles/kernel/kernel_types.h
    trunk/blender/intern/cycles/kernel/svm/bsdf_ward.h
    trunk/blender/intern/cycles/kernel/svm/svm.h
    trunk/blender/intern/cycles/kernel/svm/svm_closure.h
    trunk/blender/intern/cycles/kernel/svm/svm_geometry.h
    trunk/blender/intern/cycles/kernel/svm/svm_types.h
    trunk/blender/intern/cycles/render/attribute.cpp
    trunk/blender/intern/cycles/render/graph.cpp
    trunk/blender/intern/cycles/render/graph.h
    trunk/blender/intern/cycles/render/nodes.cpp
    trunk/blender/intern/cycles/render/nodes.h
    trunk/blender/intern/cycles/util/util_types.h
    trunk/blender/source/blender/blenkernel/intern/node.c
    trunk/blender/source/blender/makesrna/intern/rna_nodetree_types.h
    trunk/blender/source/blender/nodes/CMakeLists.txt
    trunk/blender/source/blender/nodes/NOD_shader.h
    trunk/blender/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c

Modified: trunk/blender/intern/cycles/blender/blender_mesh.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_mesh.cpp	2012-10-10 12:54:36 UTC (rev 51257)
+++ trunk/blender/intern/cycles/blender/blender_mesh.cpp	2012-10-10 13:02:20 UTC (rev 51258)
@@ -33,6 +33,28 @@
 
 /* Find/Add */
 
+static float3 tri_calc_tangent(float3 v0, float3 v1, float3 v2, float3 tx0, float3 tx1, float3 tx2)
+{
+	float3 duv1 = tx2 - tx0;
+	float3 duv2 = tx2 - tx1;
+	float3 dp1 = v2 - v0;
+	float3 dp2 = v2 - v1;
+	float det = duv1[0] * duv2[1] - duv1[1] * duv2[0];
+
+	if(det != 0.0f) {
+		return normalize(dp1 * duv2[1] - dp2 * duv1[1]);
+	}
+	else {
+		/* give back a sane default, using a valid edge as a fallback */
+		float3 edge = v1 - v0;
+
+		if(len(edge) == 0.0f)
+			edge = v2 - v0;
+
+		return normalize(edge);
+	}
+}
+
 static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders)
 {
 	/* create vertices */
@@ -157,6 +179,67 @@
 			}
 		}
 	}
+
+	/* create texcoord-based tangent attributes */
+	{
+		BL::Mesh::tessface_uv_textures_iterator l;
+
+		for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
+			AttributeStandard std = (l->active_render())? ATTR_STD_TANGENT: ATTR_STD_NONE;
+
+			if(!mesh->need_attribute(scene, std))
+				continue;
+
+			Attribute *attr = mesh->attributes.add(std, ustring("Tangent"));
+
+			/* compute average tangents per vertex */
+			float3 *tangents = attr->data_float3();
+			memset(tangents, 0, sizeof(float3)*mesh->verts.size());
+
+			BL::MeshTextureFaceLayer::data_iterator t;
+
+			size_t fi = 0; /* face index */
+			b_mesh.tessfaces.begin(f);
+			for(l->data.begin(t); t != l->data.end() && f != b_mesh.tessfaces.end(); ++t, ++fi, ++f) {
+				int4 vi = get_int4(f->vertices_raw());
+
+				float3 tx0 = get_float3(t->uv1());
+				float3 tx1 = get_float3(t->uv2());
+				float3 tx2 = get_float3(t->uv3());
+
+				float3 v0 = mesh->verts[vi[0]];
+				float3 v1 = mesh->verts[vi[1]];
+				float3 v2 = mesh->verts[vi[2]];
+
+				/* calculate tangent for the triangle;
+				 * get vertex positions, and find change in position with respect
+				 * to the texture coords in the first texture coord dimension */
+				float3 tangent0 = tri_calc_tangent(v0, v1, v2, tx0, tx1, tx2);
+
+				if(nverts[fi] == 4) {
+					/* quad tangent */
+					float3 tx3 = get_float3(t->uv4());
+					float3 v3 = mesh->verts[vi[3]];
+					float3 tangent1 = tri_calc_tangent(v0, v2, v3, tx0, tx2, tx3);
+
+					tangents[vi[0]] += 0.5f*(tangent0 + tangent1);
+					tangents[vi[1]] += tangent0;
+					tangents[vi[2]] += 0.5f*(tangent0 + tangent1);
+					tangents[vi[3]] += tangent1;
+				}
+				else {
+					/* triangle tangent */
+					tangents[vi[0]] += tangent0;
+					tangents[vi[1]] += tangent0;
+					tangents[vi[2]] += tangent0;
+				}
+			}
+
+			/* normalize tangent vectors */
+			for(int i = 0; i < mesh->verts.size(); i++)
+				tangents[i] = normalize(tangents[i]);
+		}
+	}
 }
 
 static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, const vector<uint>& used_shaders)

Modified: trunk/blender/intern/cycles/blender/blender_shader.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_shader.cpp	2012-10-10 12:54:36 UTC (rev 51257)
+++ trunk/blender/intern/cycles/blender/blender_shader.cpp	2012-10-10 13:02:20 UTC (rev 51258)
@@ -315,6 +315,10 @@
 			node = new HoldoutNode();
 			break;
 		}
+		case BL::ShaderNode::type_BSDF_ANISOTROPIC: {
+			node = new WardBsdfNode();
+			break;
+		}
 		case BL::ShaderNode::type_BSDF_DIFFUSE: {
 			node = new DiffuseBsdfNode();
 			break;

Modified: trunk/blender/intern/cycles/kernel/kernel_montecarlo.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_montecarlo.h	2012-10-10 12:54:36 UTC (rev 51257)
+++ trunk/blender/intern/cycles/kernel/kernel_montecarlo.h	2012-10-10 13:02:20 UTC (rev 51258)
@@ -72,7 +72,7 @@
 
 __device void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b)
 {
-	*b = cross(N, T);
+	*b = normalize(cross(N, T));
 	*a = cross(*b, N);
 }
 

Modified: trunk/blender/intern/cycles/kernel/kernel_shader.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_shader.h	2012-10-10 12:54:36 UTC (rev 51257)
+++ trunk/blender/intern/cycles/kernel/kernel_shader.h	2012-10-10 13:02:20 UTC (rev 51258)
@@ -93,6 +93,7 @@
 #ifdef __DPDU__
 	/* dPdu/dPdv */
 	triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
+	sd->T = make_float3(0.0f, 0.0f, 0.0f);
 #endif
 
 #ifdef __INSTANCING__
@@ -117,6 +118,7 @@
 #ifdef __DPDU__
 		sd->dPdu = -sd->dPdu;
 		sd->dPdv = -sd->dPdv;
+		sd->T = make_float3(0.0f, 0.0f, 0.0f);
 #endif
 	}
 
@@ -208,6 +210,8 @@
 		}
 #endif
 	}
+
+   	sd->T = make_float3(0.0f, 0.0f, 0.0f);
 #endif
 
 	/* backfacing test */
@@ -293,6 +297,7 @@
 	/* dPdu/dPdv */
 	sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
 	sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
+	sd->T = make_float3(0.0f, 0.0f, 0.0f);
 #endif
 
 #ifdef __RAY_DIFFERENTIALS__

Modified: trunk/blender/intern/cycles/kernel/kernel_types.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_types.h	2012-10-10 12:54:36 UTC (rev 51257)
+++ trunk/blender/intern/cycles/kernel/kernel_types.h	2012-10-10 13:02:20 UTC (rev 51258)
@@ -447,6 +447,9 @@
 	/* differential of P w.r.t. parametric coordinates. note that dPdu is
 	 * not readily suitable as a tangent for shading on triangles. */
 	float3 dPdu, dPdv;
+
+	/* tangent for shading */
+	float3 T;
 #endif
 
 #ifdef __MULTI_CLOSURE__

Modified: trunk/blender/intern/cycles/kernel/svm/bsdf_ward.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/bsdf_ward.h	2012-10-10 12:54:36 UTC (rev 51257)
+++ trunk/blender/intern/cycles/kernel/svm/bsdf_ward.h	2012-10-10 13:02:20 UTC (rev 51258)
@@ -67,7 +67,7 @@
 	float m_ax = sc->data0;
 	float m_ay = sc->data1;
 	float3 m_N = sd->N;
-	float3 m_T = normalize(sd->dPdu);
+	float3 m_T = sd->T;
 
 	float cosNO = dot(m_N, I);
 	float cosNI = dot(m_N, omega_in);
@@ -90,6 +90,7 @@
 		*pdf = exp_val / denom;
 		return make_float3 (out, out, out);
 	}
+
 	return make_float3 (0, 0, 0);
 }
 
@@ -108,7 +109,7 @@
 	float m_ax = sc->data0;
 	float m_ay = sc->data1;
 	float3 m_N = sd->N;
-	float3 m_T = normalize(sd->dPdu);
+	float3 m_T = sd->T;
 
 	float cosNO = dot(m_N, sd->I);
 	if(cosNO > 0) {

Modified: trunk/blender/intern/cycles/kernel/svm/svm.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/svm.h	2012-10-10 12:54:36 UTC (rev 51257)
+++ trunk/blender/intern/cycles/kernel/svm/svm.h	2012-10-10 13:02:20 UTC (rev 51258)
@@ -205,6 +205,14 @@
 			case NODE_CLOSURE_WEIGHT:
 				svm_node_closure_weight(sd, stack, node.y);
 				break;
+#ifdef __DPDU__
+			case NODE_CLOSURE_SET_TANGENT:
+				svm_node_closure_set_tangent(sd, node.y, node.z, node.w);
+				break;
+			case NODE_CLOSURE_TANGENT:
+				svm_node_closure_tangent(sd, stack, node.y);
+				break;
+#endif
 			case NODE_EMISSION_WEIGHT:
 				svm_node_emission_weight(kg, sd, stack, node);
 				break;
@@ -261,14 +269,14 @@
 				svm_node_camera(kg, sd, stack, node.y, node.z, node.w);
 				break;
 			case NODE_GEOMETRY:
-				svm_node_geometry(sd, stack, node.y, node.z);
+				svm_node_geometry(kg, sd, stack, node.y, node.z);
 				break;
 #ifdef __EXTRA_NODES__
 			case NODE_GEOMETRY_BUMP_DX:
-				svm_node_geometry_bump_dx(sd, stack, node.y, node.z);
+				svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z);
 				break;
 			case NODE_GEOMETRY_BUMP_DY:
-				svm_node_geometry_bump_dy(sd, stack, node.y, node.z);
+				svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z);
 				break;
 			case NODE_LIGHT_PATH:
 				svm_node_light_path(sd, stack, node.y, node.z, path_flag);

Modified: trunk/blender/intern/cycles/kernel/svm/svm_closure.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/svm_closure.h	2012-10-10 12:54:36 UTC (rev 51257)
+++ trunk/blender/intern/cycles/kernel/svm/svm_closure.h	2012-10-10 13:02:20 UTC (rev 51258)
@@ -179,7 +179,7 @@
 			float roughness_u = param1;
 			float roughness_v = param2;
 
-			bsdf_ward_setup(sd, sc, normalize(sd->dPdu), roughness_u, roughness_v);
+			bsdf_ward_setup(sd, sc, normalize(sd->T), roughness_u, roughness_v);
 			break;
 		}
 #endif
@@ -425,5 +425,24 @@
 #endif
 }
 
+#ifdef __DPDU__
+__device_inline void svm_node_closure_store_tangent(ShaderData *sd, float3 tangent)
+{
+	sd->T = normalize(tangent);
+}
+
+__device void svm_node_closure_set_tangent(ShaderData *sd, uint x, uint y, uint z)
+{
+	float3 tangent = make_float3(__int_as_float(x), __int_as_float(y), __int_as_float(z));
+	svm_node_closure_store_tangent(sd, tangent);
+}
+
+__device void svm_node_closure_tangent(ShaderData *sd, float *stack, uint tangent_offset)
+{
+	float3 tangent = stack_load_float3(stack, tangent_offset);
+	svm_node_closure_store_tangent(sd, tangent);
+}
+#endif
+
 CCL_NAMESPACE_END
 

Modified: trunk/blender/intern/cycles/kernel/svm/svm_geometry.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/svm_geometry.h	2012-10-10 12:54:36 UTC (rev 51257)
+++ trunk/blender/intern/cycles/kernel/svm/svm_geometry.h	2012-10-10 13:02:20 UTC (rev 51258)
@@ -20,7 +20,7 @@
 
 /* Geometry Node */
 
-__device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint out_offset)
+__device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
 {
 	float3 data;
 
@@ -28,7 +28,16 @@
 		case NODE_GEOM_P: data = sd->P; break;
 		case NODE_GEOM_N: data = sd->N; break;
 #ifdef __DPDU__
-		case NODE_GEOM_T: data = normalize(sd->dPdu); break;
+		case NODE_GEOM_T: {
+			int attr_offset = find_attribute(kg, sd, ATTR_STD_TANGENT);
+
+			if(attr_offset == ATTR_STD_NOT_FOUND)
+				data = normalize(sd->dPdu);
+			else
+				data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
+
+			break;
+		}
 #endif
 		case NODE_GEOM_I: data = sd->I; break;
 		case NODE_GEOM_Ng: data = sd->Ng; break;
@@ -40,7 +49,7 @@
 	stack_store_float3(stack, out_offset, data);
 }
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list