[Bf-blender-cvs] [27043b8] master: Cycles code internals: add support for mesh voxel grid attributes.

Brecht Van Lommel noreply at git.blender.org
Sat Mar 29 15:33:13 CET 2014


Commit: 27043b8e40f74c8b0917850d1aefbd6315fa46a5
Author: Brecht Van Lommel
Date:   Sat Mar 29 13:03:48 2014 +0100
https://developer.blender.org/rB27043b8e40f74c8b0917850d1aefbd6315fa46a5

Cycles code internals: add support for mesh voxel grid attributes.

These are internally stored as a 3D image textures, but accessible like e.g.
UV coordinates though the attribute node and getattribute().

This is convenient for rendering e.g. smoke objects where data like density is
really a property of the mesh, and it avoids having to specify the smoke object
in a texture node, instead the material will work with any smoke domain.

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

M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/geom/geom.h
M	intern/cycles/kernel/geom/geom_attribute.h
M	intern/cycles/kernel/geom/geom_primitive.h
A	intern/cycles/kernel/geom/geom_volume.h
M	intern/cycles/kernel/kernel_types.h
M	intern/cycles/kernel/osl/osl_services.cpp
M	intern/cycles/kernel/svm/svm_attribute.h
M	intern/cycles/kernel/svm/svm_tex_coord.h
M	intern/cycles/render/attribute.cpp
M	intern/cycles/render/attribute.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/nodes.cpp

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

diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index e473b1a..45b4c81 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -119,6 +119,7 @@ set(SRC_GEOM_HEADERS
 	geom/geom_object.h
 	geom/geom_primitive.h
 	geom/geom_triangle.h
+	geom/geom_volume.h
 )
 
 set(SRC_UTIL_HEADERS
diff --git a/intern/cycles/kernel/geom/geom.h b/intern/cycles/kernel/geom/geom.h
index a4e9bdb..9495a25 100644
--- a/intern/cycles/kernel/geom/geom.h
+++ b/intern/cycles/kernel/geom/geom.h
@@ -38,6 +38,7 @@
 #include "geom_motion_triangle.h"
 #include "geom_motion_curve.h"
 #include "geom_curve.h"
+#include "geom_volume.h"
 #include "geom_primitive.h"
 #include "geom_bvh.h"
 
diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h
index cbc1fb4..63ce31c 100644
--- a/intern/cycles/kernel/geom/geom_attribute.h
+++ b/intern/cycles/kernel/geom/geom_attribute.h
@@ -32,35 +32,29 @@ ccl_device_inline int find_attribute(KernelGlobals *kg, const ShaderData *sd, ui
 	if(sd->object == PRIM_NONE)
 		return (int)ATTR_STD_NOT_FOUND;
 
-#ifdef __OSL__
-	if (kg->osl) {
-		return OSLShader::find_attribute(kg, sd, id, elem);
-	}
-	else
-#endif
-	{
-		/* for SVM, find attribute by unique id */
-		uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
+	/* for SVM, find attribute by unique id */
+	uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
 #ifdef __HAIR__
-		attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
+	attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
 #endif
-		uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-		
-		while(attr_map.x != id) {
-			attr_offset += ATTR_PRIM_TYPES;
-			attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
-		}
+	uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+	
+	while(attr_map.x != id) {
+		attr_offset += ATTR_PRIM_TYPES;
+		attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
+	}
 
-		*elem = (AttributeElement)attr_map.y;
-		
-		if(sd->prim == PRIM_NONE && (AttributeElement)attr_map.y != ATTR_ELEMENT_MESH)
-			return ATTR_STD_NOT_FOUND;
+	*elem = (AttributeElement)attr_map.y;
+	
+	if(sd->prim == PRIM_NONE && (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;
-	}
+	/* return result */
+	return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
 }
 
+/* Transform matrix attribute on meshes */
+
 ccl_device Transform primitive_attribute_matrix(KernelGlobals *kg, const ShaderData *sd, int offset)
 {
 	Transform tfm;
diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h
index d90cc10..f821e69 100644
--- a/intern/cycles/kernel/geom/geom_primitive.h
+++ b/intern/cycles/kernel/geom/geom_primitive.h
@@ -25,26 +25,46 @@ CCL_NAMESPACE_BEGIN
 
 ccl_device float primitive_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float *dx, float *dy)
 {
-#ifdef __HAIR__
-	if(sd->type & PRIMITIVE_ALL_TRIANGLE)
-#endif
+	if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
 		return triangle_attribute_float(kg, sd, elem, offset, dx, dy);
+	}
 #ifdef __HAIR__
-	else
+	else if(sd->type & PRIMITIVE_ALL_CURVE) {
 		return curve_attribute_float(kg, sd, elem, offset, dx, dy);
+	}
 #endif
+#ifdef __VOLUME__
+	else if(sd->object != OBJECT_NONE && elem == ATTR_ELEMENT_VOXEL) {
+		return volume_attribute_float(kg, sd, elem, offset, dx, dy);
+	}
+#endif
+	else {
+		if(dx) *dx = 0.0f;
+		if(dy) *dy = 0.0f;
+		return 0.0f;
+	}
 }
 
 ccl_device float3 primitive_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int offset, float3 *dx, float3 *dy)
 {
-#ifdef __HAIR__
-	if(sd->type & PRIMITIVE_ALL_TRIANGLE)
-#endif
+	if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
 		return triangle_attribute_float3(kg, sd, elem, offset, dx, dy);
+	}
 #ifdef __HAIR__
-	else
+	else if(sd->type & PRIMITIVE_ALL_CURVE) {
 		return curve_attribute_float3(kg, sd, elem, offset, dx, dy);
+	}
+#endif
+#ifdef __VOLUME__
+	else if(sd->object != OBJECT_NONE && elem == ATTR_ELEMENT_VOXEL) {
+		return volume_attribute_float3(kg, sd, elem, offset, dx, dy);
+	}
 #endif
+	else {
+		if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+		if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+		return make_float3(0.0f, 0.0f, 0.0f);
+	}
 }
 
 /* Default UV coordinate */
diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h
new file mode 100644
index 0000000..963d6cb
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_volume.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011-2013 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/* Volume Primitive
+ *
+ * Volumes are just regions inside meshes with the mesh surface as boundaries.
+ * There isn't as much data to access as for surfaces, there is only a position
+ * to do lookups in 3D voxel or procedural textures.
+ *
+ * 3D voxel textures can be assigned as attributes per mesh, which means the
+ * same shader can be used for volume objects with different densities, etc. */
+
+CCL_NAMESPACE_BEGIN
+
+#ifdef __VOLUME__
+
+/* Return position normalized to 0..1 in mesh bounds */
+
+ccl_device float3 volume_normalized_position(KernelGlobals *kg, const ShaderData *sd, float3 P)
+{
+	/* todo: optimize this so it's just a single matrix multiplication when
+	 * possible (not motion blur), or perhaps even just translation + scale */
+	AttributeElement attr_elem;
+	int attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED_TRANSFORM, &attr_elem);
+
+	object_inverse_position_transform(kg, sd, &P);
+
+	if(attr_offset != ATTR_STD_NOT_FOUND) {
+		Transform tfm = primitive_attribute_matrix(kg, sd, attr_offset);
+		P = transform_point(&tfm, P);
+	}
+
+	return P;
+}
+
+ccl_device float volume_attribute_float(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int id, float *dx, float *dy)
+{
+	float3 P = volume_normalized_position(kg, sd, sd->P);
+	float4 r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
+
+	if(dx) *dx = 0.0f;
+	if(dx) *dy = 0.0f;
+
+	/* todo: support float textures to lower memory usage for single floats */
+	return average(float4_to_float3(r));
+}
+
+ccl_device float3 volume_attribute_float3(KernelGlobals *kg, const ShaderData *sd, AttributeElement elem, int id, float3 *dx, float3 *dy)
+{
+	float3 P = volume_normalized_position(kg, sd, sd->P);
+	float4 r = kernel_tex_image_interp_3d(id, P.x, P.y, P.z);
+
+	if(dx) *dx = make_float3(0.0f, 0.0f, 0.0f);
+	if(dy) *dy = make_float3(0.0f, 0.0f, 0.0f);
+
+	return float4_to_float3(r);
+}
+
+#endif
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 0be83e5..f7aebd2 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -459,7 +459,8 @@ typedef enum AttributeElement {
 	ATTR_ELEMENT_CORNER,
 	ATTR_ELEMENT_CURVE,
 	ATTR_ELEMENT_CURVE_KEY,
-	ATTR_ELEMENT_CURVE_KEY_MOTION
+	ATTR_ELEMENT_CURVE_KEY_MOTION,
+	ATTR_ELEMENT_VOXEL
 } AttributeElement;
 
 typedef enum AttributeStandard {
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 65548d6..d5edd04 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -768,9 +768,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
 
 		if (attr.elem != ATTR_ELEMENT_OBJECT) {
 			/* triangle and vertex attributes */
-			if (prim != PRIM_NONE)
-				return get_mesh_element_attribute(kg, sd, attr, type, derivatives, val);
-			else
+			if(!get_mesh_element_attribute(kg, sd, attr, type, derivatives, val))
 				return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
 		}
 		else {
diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h
index 2592bbe..fd0ea7f 100644
--- a/intern/cycles/kernel/svm/svm_attribute.h
+++ b/intern/cycles/kernel/svm/svm_attribute.h
@@ -22,12 +22,12 @@ ccl_device void svm_node_attr_init(KernelGlobals *kg, ShaderData *sd,
 	uint4 node, NodeAttributeType *type,
 	NodeAttributeType *mesh_type, AttributeElement *elem, int *offset, uint *out_offset)
 {
-	if(sd->object != OBJECT_NONE && sd->prim != PRIM_NONE) {
+	if(sd->object != OBJECT_NONE) {
 		/* find attribute by unique id */
 		uint id = node.y;
 		uint attr_offset = sd->object*kernel_data.bvh.attributes_map_stride;
 #ifdef __HAIR__
-		attr_offset = (sd->type & PRIMITIVE_ALL_TRIANGLE)? attr_offset: attr_offset + ATTR_PRIM_CURVE;
+		attr_offset = (sd->type & PRIMITIVE_ALL_CURVE)? attr_offset + ATTR_PRIM_CURVE: attr_offset;
 #endif
 		uint4 attr_map = kernel_tex_fetch(__attributes_map, attr_offset);
 		
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index bddeac0..a17e4a2 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -70,17 +70,10 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, int path_f
 		case NODE_TEXCO_VOLUME_GENERATED: {
 			data = sd->P;
 
-			if(sd->object != OBJECT_NONE) {
-				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, dat

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list