[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51875] trunk/blender: Cycles: improve Anisotropic BSDF node, changing the Roughness U/V inputs to

Brecht Van Lommel brechtvanlommel at pandora.be
Sun Nov 4 23:31:33 CET 2012


Revision: 51875
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51875
Author:   blendix
Date:     2012-11-04 22:31:32 +0000 (Sun, 04 Nov 2012)
Log Message:
-----------
Cycles: improve Anisotropic BSDF node, changing the Roughness U/V inputs to
Roughness, Anisotropy and Rotation. Also a fix for automatic tangents and
OSL attribute handling.

Meaning of new sockets explained in the documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Shaders#Anisotropic

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/blender_mesh.cpp
    trunk/blender/intern/cycles/kernel/kernel_object.h
    trunk/blender/intern/cycles/kernel/osl/osl_services.cpp
    trunk/blender/intern/cycles/kernel/shaders/node_geometry.osl
    trunk/blender/intern/cycles/kernel/shaders/node_ward_bsdf.osl
    trunk/blender/intern/cycles/kernel/svm/svm_closure.h
    trunk/blender/intern/cycles/kernel/svm/svm_geometry.h
    trunk/blender/intern/cycles/render/mesh.cpp
    trunk/blender/intern/cycles/render/nodes.cpp
    trunk/blender/intern/cycles/render/nodes.h
    trunk/blender/intern/cycles/util/util_attribute.cpp
    trunk/blender/intern/cycles/util/util_math.h
    trunk/blender/source/blender/gpu/shaders/gpu_shader_material.glsl
    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-11-04 22:31:21 UTC (rev 51874)
+++ trunk/blender/intern/cycles/blender/blender_mesh.cpp	2012-11-04 22:31:32 UTC (rev 51875)
@@ -141,7 +141,7 @@
 
 	/* create attribute */
 	/* todo: create float4 attribute for sign */
-	Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent"));
+	Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("tangent"));
 	float3 *tangent = attr->data_float3();
 
 	for (int i = 0; i < nverts.size(); i++) {

Modified: trunk/blender/intern/cycles/kernel/kernel_object.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_object.h	2012-11-04 22:31:21 UTC (rev 51874)
+++ trunk/blender/intern/cycles/kernel/kernel_object.h	2012-11-04 22:31:32 UTC (rev 51875)
@@ -84,7 +84,8 @@
 	}
 	else {
 		Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
-		*itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+		if(itfm)
+			*itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
 
 		return tfm;
 	}

Modified: trunk/blender/intern/cycles/kernel/osl/osl_services.cpp
===================================================================
--- trunk/blender/intern/cycles/kernel/osl/osl_services.cpp	2012-11-04 22:31:21 UTC (rev 51874)
+++ trunk/blender/intern/cycles/kernel/osl/osl_services.cpp	2012-11-04 22:31:32 UTC (rev 51875)
@@ -393,25 +393,25 @@
 static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
                                const TypeDesc& type, bool derivatives, void *val)
 {
-	if (attr.type == TypeDesc::TypeFloat) {
-		float fval[3];
-		fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
-		                                   (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
-		set_attribute_float(fval, type, derivatives, val);
-		return true;
-	}
-	else if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
+	if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
 	         attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
 	{
-		/* todo: this won't work when float3 has w component */
 		float3 fval[3];
 		fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset,
 		                                    (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
 		set_attribute_float3(fval, type, derivatives, val);
 		return true;
 	}
-	else
+	else if (attr.type == TypeDesc::TypeFloat) {
+		float fval[3];
+		fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
+		                                   (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+		set_attribute_float(fval, type, derivatives, val);
+		return true;
+	}
+	else {
 		return false;
+	}
 }
 
 static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivatives, void *val)
@@ -598,7 +598,7 @@
 
 	if (it != attribute_map.end()) {
 		const OSLGlobals::Attribute& attr = it->second;
-		
+
 		if (attr.elem != ATTR_ELEMENT_VALUE) {
 			/* triangle and vertex attributes */
 			if (tri != ~0)
@@ -613,11 +613,11 @@
 	else {
 		/* not found in attribute, check standard object info */
 		bool is_std_object_attribute = get_object_standard_attribute(kg, sd, name, type, derivatives, val);
+
 		if (is_std_object_attribute)
 			return true;
-		else {
-			return get_background_attribute(kg, sd, name, type, derivatives, val);
-		}
+
+		return get_background_attribute(kg, sd, name, type, derivatives, val);
 	}
 
 	return false;

Modified: trunk/blender/intern/cycles/kernel/shaders/node_geometry.osl
===================================================================
--- trunk/blender/intern/cycles/kernel/shaders/node_geometry.osl	2012-11-04 22:31:21 UTC (rev 51874)
+++ trunk/blender/intern/cycles/kernel/shaders/node_geometry.osl	2012-11-04 22:31:32 UTC (rev 51875)
@@ -32,7 +32,6 @@
 {
 	Position = P;
 	Normal = NormalIn;
-	Tangent = normalize(dPdu);
 	TrueNormal = Ng;
 	Incoming = I;
 	Parametric = point(u, v, 0.0);
@@ -46,5 +45,28 @@
 		Position += Dy(Position);
 		Parametric += Dy(Parametric);
 	}
+
+	/* first try to get tangent attribute */
+	vector T;
+
+	if (getattribute("geom:tangent", T)) {
+		/* ensure orthogonal and normalized (interpolation breaks it) */
+		T = transform("object", "world", T);
+		Tangent = cross(Normal, normalize(cross(T, Normal)));
+	}
+	else {
+		point generated;
+
+		/* try to create spherical tangent from generated coordinates */
+		if (getattribute("geom:generated", generated)) {
+			T = vector(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
+			T = transform("object", "world", T);
+			Tangent = cross(Normal, normalize(cross(T, Normal)));
+		}
+		else {
+			/* otherwise use surface derivatives */
+			Tangent = normalize(dPdu);
+		}
+	}
 }
 

Modified: trunk/blender/intern/cycles/kernel/shaders/node_ward_bsdf.osl
===================================================================
--- trunk/blender/intern/cycles/kernel/shaders/node_ward_bsdf.osl	2012-11-04 22:31:21 UTC (rev 51874)
+++ trunk/blender/intern/cycles/kernel/shaders/node_ward_bsdf.osl	2012-11-04 22:31:32 UTC (rev 51875)
@@ -20,11 +20,32 @@
 
 shader node_ward_bsdf(
 	color Color = color(0.8, 0.8, 0.8),
-	float RoughnessU = 0.0,
-	float RoughnessV = 0.0,
+	float Roughness = 0.0,
+	float Anisotropy = 0.0,
+	float Rotation = 0.0,
 	normal Normal = N,
+	normal Tangent = normalize(dPdu),
 	output closure color BSDF = diffuse(Normal))
 {
-	BSDF = Color * ward(Normal, normalize(dPdu), RoughnessU, RoughnessV);
+	/* rotate tangent around normal */
+	vector T = Tangent;
+
+	if(Rotation != 0.0)
+		T = rotate(T, Rotation*2.0*M_PI, point(0.0, 0.0, 0.0), Normal);
+
+	/* compute roughness */
+	float RoughnessU, RoughnessV;
+	float aniso = clamp(Anisotropy, -0.99, 0.99);
+
+	if(aniso < 0.0) {
+		RoughnessU = Roughness*(1.0 + aniso);
+		RoughnessV = Roughness/(1.0 + aniso);
+	}
+	else {
+		RoughnessU = Roughness/(1.0 - aniso);
+		RoughnessV = Roughness*(1.0 - aniso);
+	}
+
+	BSDF = Color * ward(Normal, T, RoughnessU, RoughnessV);
 }
 

Modified: trunk/blender/intern/cycles/kernel/svm/svm_closure.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/svm_closure.h	2012-11-04 22:31:21 UTC (rev 51874)
+++ trunk/blender/intern/cycles/kernel/svm/svm_closure.h	2012-11-04 22:31:32 UTC (rev 51875)
@@ -211,9 +211,25 @@
 			sc->T = stack_load_float3(stack, data_node.z);
 			svm_node_closure_set_mix_weight(sc, mix_weight);
 
-			sc->data0 = param1;
-			sc->data1 = param2;
+			/* rotate tangent */
+			float rotation = stack_load_float(stack, data_node.w);
 
+			if(rotation != 0.0f)
+				sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
+
+			/* compute roughness */
+			float roughness = param1;
+			float anisotropy = clamp(param2, -0.99f, 0.99f);
+
+			if(anisotropy < 0.0f) {
+				sc->data0 = roughness*(1.0f + anisotropy);
+				sc->data1 = roughness/(1.0f + anisotropy);
+			}
+			else {
+				sc->data0 = roughness/(1.0f - anisotropy);
+				sc->data1 = roughness*(1.0f - anisotropy);
+			}
+
 			sd->flag |= bsdf_ward_setup(sc);
 			break;
 		}

Modified: trunk/blender/intern/cycles/kernel/svm/svm_geometry.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/svm_geometry.h	2012-11-04 22:31:21 UTC (rev 51874)
+++ trunk/blender/intern/cycles/kernel/svm/svm_geometry.h	2012-11-04 22:31:32 UTC (rev 51875)
@@ -20,22 +20,6 @@
 
 /* Geometry Node */
 
-__device_inline float3 svm_tangent_from_generated(float3 P)
-{
-	float length = len(P);
-
-	if(length == 0.0f)
-		return make_float3(0.0f, 0.0f, 0.0f);
-
-	float u = 0.0f;
-	if(!(P.x == 0.0f && P.y == 0.0f))
-		u = (1.0f - atan2f(P.x, P.y))/(2.0f*M_PI_F);
-	
-	float v = 1.0f - acosf(clamp(P.z/length, -1.0f, 1.0f))/M_PI_F;
-
-	return make_float3(u, v, 0.0f);
-}
-
 __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
 {
 	float3 data;
@@ -45,27 +29,30 @@
 		case NODE_GEOM_N: data = sd->N; break;
 #ifdef __DPDU__
 		case NODE_GEOM_T: {
-			if(sd->object != ~0) {
-				int attr_offset = find_attribute(kg, sd, ATTR_STD_TANGENT);
+			/* first try to get tangent attribute */
+			int attr_offset = (sd->object != ~0)? find_attribute(kg, sd, ATTR_STD_TANGENT): ATTR_STD_NOT_FOUND;
 
+			if(attr_offset != ATTR_STD_NOT_FOUND) {
+				/* ensure orthogonal and normalized (interpolation breaks it) */
+				data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
+				object_normal_transform(kg, sd, &data);
+				data = cross(sd->N, normalize(cross(data, sd->N)));;
+			}
+			else {
+				/* try to create spherical tangent from generated coordinates */
+				int attr_offset = (sd->object != ~0)? find_attribute(kg, sd, ATTR_STD_GENERATED): ATTR_STD_NOT_FOUND;
+
 				if(attr_offset != ATTR_STD_NOT_FOUND) {
-					data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
+					data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
+					data = make_float3(-(data.y - 0.5), (data.x - 0.5), 0.0f);
 					object_normal_transform(kg, sd, &data);
+					data = cross(sd->N, normalize(cross(data, sd->N)));;
 				}
 				else {
-					attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED);
-
-					if(attr_offset != ATTR_STD_NOT_FOUND) {
-						data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
-						svm_tangent_from_generated(data);
-						object_normal_transform(kg, sd, &data);
-					}
-					else
-						data = normalize(sd->dPdu);
+					/* otherwise use surface derivatives */
+					data = normalize(sd->dPdu);
 				}
 			}
-			else
-				data = normalize(sd->dPdu);
 
 			break;
 		}

Modified: trunk/blender/intern/cycles/render/mesh.cpp
===================================================================
--- trunk/blender/intern/cycles/render/mesh.cpp	2012-11-04 22:31:21 UTC (rev 51874)
+++ trunk/blender/intern/cycles/render/mesh.cpp	2012-11-04 22:31:32 UTC (rev 51875)
@@ -355,6 +355,9 @@
 
 		/* set object attributes */
 		foreach(AttributeRequest& req, attributes.requests) {
+			if(req.element == ATTR_ELEMENT_NONE)
+				continue;
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list