[Bf-blender-cvs] [227a940] master: Cycles: implement pointiness geometry attribute

Sergey Sharybin noreply at git.blender.org
Tue Feb 10 17:01:08 CET 2015


Commit: 227a94077f508a47fe7595b9091ab86aecde4ad5
Author: Sergey Sharybin
Date:   Fri Feb 6 12:35:46 2015 +0500
Branches: master
https://developer.blender.org/rB227a94077f508a47fe7595b9091ab86aecde4ad5

Cycles: implement pointiness geometry attribute

This attribute means how "pointy" the geometry surface is, which allows to do
effects like dirt maps and wear-off effects on render geometry. This means the
attribute is calculated for the final mesh which means no baking (which implies
UV unwrap) is needed. Apart from this the behavior is quite close to how vertex
dirty colors works.

The new attribute is available as an output socket of Geometry node.

There's no penalty for the render time, only some delay on scene preparation
(the delay is linear of the mesh complexity).

Reviewers: brecht, juicyfruit

Subscribers: eyecandy, venomgfx

Differential Revision: https://developer.blender.org/D1086

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

M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/shaders/node_geometry.osl
M	intern/cycles/render/attribute.cpp
M	intern/cycles/render/nodes.cpp
M	source/blender/nodes/shader/nodes/node_shader_geometry.c

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

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 10b037a..a02449a 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -28,6 +28,7 @@
 
 #include "util_foreach.h"
 #include "util_logging.h"
+#include "util_math.h"
 
 #include "mikktspace.h"
 
@@ -387,6 +388,68 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
 		}
 	}
 
+	/* create vertex pointiness attributes */
+	/* TODO(sergey): Consider moving all the attribute creation into own
+	 * functions for clarity.
+	 */
+	{
+		if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
+			Attribute *attr = mesh->attributes.add(ATTR_STD_POINTINESS);
+			float *data = attr->data_float();
+			int *counter = new int[numverts];
+			float *raw_data = new float[numverts];
+			float3 *edge_accum = new float3[numverts];
+
+			/* Calculate pointiness using single ring neighborhood. */
+			memset(counter, 0, sizeof(int) * numverts);
+			memset(raw_data, 0, sizeof(float) * numverts);
+			memset(edge_accum, 0, sizeof(float3) * numverts);
+			BL::Mesh::edges_iterator e;
+			i = 0;
+			for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
+				int v0 = b_mesh.edges[i].vertices()[0],
+				    v1 = b_mesh.edges[i].vertices()[1];
+				float3 co0 = get_float3(b_mesh.vertices[v0].co()),
+				       co1 = get_float3(b_mesh.vertices[v1].co());
+				edge_accum[v0] += normalize(co1 - co0);
+				edge_accum[v1] += normalize(co0 - co1);
+				++counter[v0];
+				++counter[v1];
+			}
+			i = 0;
+			for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) {
+				if(counter[i] > 0) {
+					float3 normal = get_float3(b_mesh.vertices[i].normal());
+					float angle = safe_acosf(dot(normal, edge_accum[i] / counter[i]));
+					raw_data[i] = angle * M_1_PI_F;
+				}
+				else {
+					raw_data[i] = 0.0f;
+				}
+			}
+
+			/* Blur vertices to approximate 2 ring neighborhood. */
+			memset(counter, 0, sizeof(int) * numverts);
+			memcpy(data, raw_data, sizeof(float) * numverts);
+			i = 0;
+			for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
+				int v0 = b_mesh.edges[i].vertices()[0],
+				    v1 = b_mesh.edges[i].vertices()[1];
+				data[v0] += raw_data[v1];
+				data[v1] += raw_data[v0];
+				++counter[v0];
+				++counter[v1];
+			}
+			for(i = 0; i < numverts; ++i) {
+				data[i] /= counter[i] + 1;
+			}
+
+			delete [] counter;
+			delete [] raw_data;
+			delete [] edge_accum;
+		}
+	}
+
 	/* create uv map attributes */
 	if (b_mesh.tessface_uv_textures.length() != 0) {
 		BL::Mesh::tessface_uv_textures_iterator l;
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 77d3ea8..680094d 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -534,6 +534,7 @@ typedef enum AttributeStandard {
 	ATTR_STD_VOLUME_FLAME,
 	ATTR_STD_VOLUME_HEAT,
 	ATTR_STD_VOLUME_VELOCITY,
+	ATTR_STD_POINTINESS,
 	ATTR_STD_NUM,
 
 	ATTR_STD_NOT_FOUND = ~0
diff --git a/intern/cycles/kernel/shaders/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl
index 580ccba..2bbaaff 100644
--- a/intern/cycles/kernel/shaders/node_geometry.osl
+++ b/intern/cycles/kernel/shaders/node_geometry.osl
@@ -26,7 +26,8 @@ shader node_geometry(
 	output normal TrueNormal = normal(0.0, 0.0, 0.0),
 	output vector Incoming = vector(0.0, 0.0, 0.0),
 	output point Parametric = point(0.0, 0.0, 0.0),
-	output float Backfacing = 0.0)
+	output float Backfacing = 0.0,
+	output float Pointiness = 0.0)
 {
 	Position = P;
 	Normal = NormalIn;
@@ -57,5 +58,7 @@ shader node_geometry(
 		/* otherwise use surface derivatives */
 		Tangent = normalize(dPdu);
 	}
+
+	getattribute("geom:pointiness", Pointiness);
 }
 
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index bf83c97..656420f 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -230,6 +230,8 @@ const char *Attribute::standard_name(AttributeStandard std)
 			return "heat";
 		case ATTR_STD_VOLUME_VELOCITY:
 			return "velocity";
+		case ATTR_STD_POINTINESS:
+			return "pointiness";
 		case ATTR_STD_NOT_FOUND:
 		case ATTR_STD_NONE:
 		case ATTR_STD_NUM:
@@ -375,6 +377,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
 			case ATTR_STD_VOLUME_VELOCITY:
 				attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_VOXEL);
 				break;
+			case ATTR_STD_POINTINESS:
+				attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+				break;
 			default:
 				assert(0);
 				break;
@@ -395,6 +400,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
 			case ATTR_STD_GENERATED_TRANSFORM:
 				attr = add(name, TypeDesc::TypeMatrix, ATTR_ELEMENT_MESH);
 				break;
+			case ATTR_STD_POINTINESS:
+				attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+				break;
 			default:
 				assert(0);
 				break;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 3448209..46c962b 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -2171,13 +2171,18 @@ GeometryNode::GeometryNode()
 	add_output("Incoming", SHADER_SOCKET_VECTOR);
 	add_output("Parametric", SHADER_SOCKET_POINT);
 	add_output("Backfacing", SHADER_SOCKET_FLOAT);
+	add_output("Pointiness", SHADER_SOCKET_FLOAT);
 }
 
 void GeometryNode::attributes(Shader *shader, AttributeRequestSet *attributes)
 {
 	if(shader->has_surface) {
-		if(!output("Tangent")->links.empty())
+		if(!output("Tangent")->links.empty()) {
 			attributes->add(ATTR_STD_GENERATED);
+		}
+		if(!output("Pointiness")->links.empty()) {
+			attributes->add(ATTR_STD_POINTINESS);
+		}
 	}
 
 	ShaderNode::attributes(shader, attributes);
@@ -2234,6 +2239,15 @@ void GeometryNode::compile(SVMCompiler& compiler)
 		compiler.stack_assign(out);
 		compiler.add_node(NODE_LIGHT_PATH, NODE_LP_backfacing, out->stack_offset);
 	}
+
+	out = output("Pointiness");
+	if(!out->links.empty()) {
+		compiler.stack_assign(out);
+		compiler.add_node(NODE_ATTR,
+		                  ATTR_STD_POINTINESS,
+		                  out->stack_offset,
+		                  NODE_ATTR_FLOAT);
+	}
 }
 
 void GeometryNode::compile(OSLCompiler& compiler)
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c
index 01851b5..553ea65 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c
@@ -37,6 +37,7 @@ static bNodeSocketTemplate sh_node_geometry_out[] = {
 	{	SOCK_VECTOR, 0, N_("Incoming"),			0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 	{	SOCK_VECTOR, 0, N_("Parametric"),		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 	{	SOCK_FLOAT,  0, N_("Backfacing"),		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+	{	SOCK_FLOAT,  0, N_("Pointiness"),		0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 	{	-1, 0, ""	}
 };




More information about the Bf-blender-cvs mailing list