[Bf-blender-cvs] [9cd2b19] master: Cycles Volume Render: generated texture coordinates for volume render.

Brecht Van Lommel noreply at git.blender.org
Tue Dec 31 17:42:17 CET 2013


Commit: 9cd2b199994ba48f343a89a270827b2e0ed3221d
Author: Brecht Van Lommel
Date:   Tue Dec 31 17:33:55 2013 +0100
https://developer.blender.org/rB9cd2b199994ba48f343a89a270827b2e0ed3221d

Cycles Volume Render: generated texture coordinates for volume render.

This does not support staying fixed while the surface deforms, but for static
meshes it should match up with the surface texture coordinates. Implemented
as a matrix transform from objects space to mesh texture space.

Making this work for deforming surfaces would be quite complicated, you might
need something like harmonic coordinates as used in the mesh deform modifier,
probably will not be possible anytime soon.

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

M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/kernel/kernel_primitive.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/osl/osl_services.cpp
M	intern/cycles/kernel/osl/osl_shader.cpp
M	intern/cycles/kernel/shaders/node_texture_coordinate.osl
M	intern/cycles/kernel/svm/svm_tex_coord.h
M	intern/cycles/kernel/svm/svm_types.h
M	intern/cycles/render/attribute.cpp
M	intern/cycles/render/attribute.h
M	intern/cycles/render/graph.cpp
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/nodes.cpp

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

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 0e46903..c761c00 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -348,9 +348,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
 		}
 	}
 
-	/* create generated coordinates. todo: we should actually get the orco
-	 * coordinates from modifiers, for now we use texspace loc/size which
-	 * is available in the api. */
+	/* create generated coordinates from undeformed coordinates */
 	if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
 		Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
 
@@ -363,6 +361,19 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
 		for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
 			generated[i++] = get_float3(v->undeformed_co())*size - loc;
 	}
+
+	/* for volume objects, create a matrix to transform from object space to
+	 * mesh texture space. this does not work with deformations but that can
+	 * probably only be done well with a volume grid mapping of coordinates */
+	if(mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
+		Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
+		Transform *tfm = attr->data_transform();
+
+		float3 loc, size;
+		mesh_texture_space(b_mesh, loc, size);
+
+		*tfm = transform_translate(-loc)*transform_scale(size);
+	}
 }
 
 static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, const vector<uint>& used_shaders)
diff --git a/intern/cycles/kernel/kernel_primitive.h b/intern/cycles/kernel/kernel_primitive.h
index 5a050c4..fa450c97 100644
--- a/intern/cycles/kernel/kernel_primitive.h
+++ b/intern/cycles/kernel/kernel_primitive.h
@@ -23,7 +23,7 @@ CCL_NAMESPACE_BEGIN
 
 ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id, AttributeElement *elem)
 {
-	if(sd->object == ~0 || sd->prim == ~0)
+	if(sd->object == ~0)
 		return (int)ATTR_STD_NOT_FOUND;
 
 #ifdef __OSL__
@@ -47,6 +47,9 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id,
 
 		*elem = (AttributeElement)attr_map.y;
 		
+		if(sd->prim == ~0 && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH)
+			return ATTR_STD_NOT_FOUND;
+
 		/* return result */
 		return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
 	}
@@ -76,6 +79,18 @@ ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData
 #endif
 }
 
+ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset)
+{
+	Transform tfm;
+
+	tfm.x = kernel_tex_fetch(__attributes_float3, offset + 0);
+	tfm.y = kernel_tex_fetch(__attributes_float3, offset + 1);
+	tfm.z = kernel_tex_fetch(__attributes_float3, offset + 2);
+	tfm.w = kernel_tex_fetch(__attributes_float3, offset + 3);
+
+	return tfm;
+}
+
 ccl_device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
 {
 	AttributeElement elem_uv;
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 1463ce9..00cb73b 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -418,7 +418,8 @@ typedef struct Intersection {
 
 typedef enum AttributeElement {
 	ATTR_ELEMENT_NONE,
-	ATTR_ELEMENT_VALUE,
+	ATTR_ELEMENT_OBJECT,
+	ATTR_ELEMENT_MESH,
 	ATTR_ELEMENT_FACE,
 	ATTR_ELEMENT_VERTEX,
 	ATTR_ELEMENT_CORNER,
@@ -434,6 +435,7 @@ typedef enum AttributeStandard {
 	ATTR_STD_UV_TANGENT,
 	ATTR_STD_UV_TANGENT_SIGN,
 	ATTR_STD_GENERATED,
+	ATTR_STD_GENERATED_TRANSFORM,
 	ATTR_STD_POSITION_UNDEFORMED,
 	ATTR_STD_POSITION_UNDISPLACED,
 	ATTR_STD_MOTION_PRE,
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index d7d3301..9b2065d 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -510,12 +510,22 @@ static bool set_attribute_float3_3(float3 P[3], TypeDesc type, bool derivatives,
 	return false;
 }
 
-static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
+static bool set_attribute_matrix(const Transform& tfm, TypeDesc type, void *val)
+{
+	if(type == TypeDesc::TypeMatrix) {
+		Transform transpose = transform_transpose(tfm);
+		memcpy(val, &transpose, sizeof(Transform));
+		return true;
+	}
+
+	return false;
+}
+
+static bool get_mesh_element_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
                                const TypeDesc& type, bool derivatives, void *val)
 {
 	if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
-	    attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
-	{
+	    attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
 		float3 fval[3];
 		fval[0] = primitive_attribute_float3(kg, sd, attr.elem, attr.offset,
 		                                     (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
@@ -532,6 +542,18 @@ static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OS
 	}
 }
 
+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::TypeMatrix) {
+		Transform tfm = primitive_attribute_matrix(kg, sd, attr.offset);
+		return set_attribute_matrix(tfm, type, val);
+	}
+	else {
+		return false;
+	}
+}
+
 static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivatives, void *val)
 {
 	size_t datasize = attr.value.datasize();
@@ -745,9 +767,11 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
 	if (it != attribute_map.end()) {
 		const OSLGlobals::Attribute& attr = it->second;
 
-		if (attr.elem != ATTR_ELEMENT_VALUE) {
+		if (attr.elem != ATTR_ELEMENT_OBJECT) {
 			/* triangle and vertex attributes */
 			if (prim != ~0)
+				return get_mesh_element_attribute(kg, sd, attr, type, derivatives, val);
+			else
 				return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
 		}
 		else {
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 6062996..554f647 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -545,6 +545,10 @@ int OSLShader::find_attribute(KernelGlobals *kg, const ShaderData *sd, uint id,
 	if (it != attr_map.end()) {
 		const OSLGlobals::Attribute &osl_attr = it->second;
 		*elem = osl_attr.elem;
+
+		if(sd->prim == ~0 && (AttributeElement)osl_attr.elem != ATTR_ELEMENT_MESH)
+			return ATTR_STD_NOT_FOUND;
+
 		/* return result */
 		return (osl_attr.elem == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : osl_attr.offset;
 	}
diff --git a/intern/cycles/kernel/shaders/node_texture_coordinate.osl b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
index 8739b77..fdd0a51 100644
--- a/intern/cycles/kernel/shaders/node_texture_coordinate.osl
+++ b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
@@ -19,6 +19,7 @@
 shader node_texture_coordinate(
 	normal NormalIn = N,
 	int is_background = 0,
+	int is_volume = 0,
 	int from_dupli = 0,
 	string bump_offset = "center",
 
@@ -45,6 +46,15 @@ shader node_texture_coordinate(
 			getattribute("geom:dupli_generated", Generated); 
 			getattribute("geom:dupli_uv", UV);
 		}
+		else if(is_volume) {
+			Generated = transform("object", P);
+
+			matrix tfm;
+			if(getattribute("geom:generated_transform", tfm))
+				Generated = transform(tfm, Generated);
+
+			getattribute("geom:uv", UV);
+		}
 		else {
 			getattribute("geom:generated", Generated); 
 			getattribute("geom:uv", UV);
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 3044cbf..4b1f30e 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -24,21 +24,15 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
 
 	switch(type) {
 		case NODE_TEXCO_OBJECT: {
-			if(sd->object != ~0) {
-				data = sd->P;
+			data = sd->P;
+			if(sd->object != ~0)
 				object_inverse_position_transform(kg, sd, &data);
-			}
-			else
-				data = sd->P;
 			break;
 		}
 		case NODE_TEXCO_NORMAL: {
-			if(sd->object != ~0) {
-				data = sd->N;
+			data = sd->N;
+			if(sd->object != ~0)
 				object_inverse_normal_transform(kg, sd, &data);
-			}
-			else
-				data = sd->N;
 			break;
 		}
 		case NODE_TEXCO_CAMERA: {
@@ -73,6 +67,22 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
 			data = object_dupli_uv(kg, sd->object);
 			break;
 		}
+		case NODE_TEXCO_VOLUME_GENERATED: {
+			data = sd->P;
+
+			if(sd->object != ~0) {
+				AttributeElement attr_elem;
+				int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
+
+				object_inverse_position_transform(kg, sd, &data);
+
+				if(attr_offset != ATTR_STD_NOT_FOUND) {
+					Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
+					data = transform_point(&tfm, data);
+				}
+			}
+			break;
+		}
 	}
 
 	stack_store_float3(stack, out_offset, data);
@@ -85,21 +95,15 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, in
 
 	switch(type) {
 		case NODE_TEXCO_OBJECT: {
-			if(sd->object != ~0) {
-				data = sd->P + sd->dP.dx;
+			data = sd->P + sd->dP.dx;
+			if(sd->object != ~0)
 				object_inverse_position_transform(kg, sd, &data);
-			}
-			else
-				data = sd->P + sd->dP.dx;
 			break;
 		}
 		case NODE_TEXCO_NORMAL: {
-			if(sd->object != ~0) {
-				data = sd->N;
+			data = sd->N;
+			if(sd->object != ~0)
 				object_inverse_normal_transform(kg, sd, &data);
-			}
-			else
-				data = sd->N;
 			break;
 		}
 		case NODE_TEXCO_CAMERA: {
@@ -134,6 +138,22 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, in
 			data = object_dupli_uv(kg, sd->object);
 			break;
 		}
+		case NODE_TEXCO_VOLUME_GENERATED: {
+			data = sd->P + sd->dP.dx;
+
+			if(sd->object != ~0) {
+				AttributeElement attr_elem;
+	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list