[Bf-blender-cvs] [7d10798] master: Cycles: Add voxel texture sampler shader node

Sergey Sharybin noreply at git.blender.org
Sat Jul 18 23:00:47 CEST 2015


Commit: 7d10798af22f683a8f55a8c361ad5676bd4160d2
Author: Sergey Sharybin
Date:   Sat Jul 18 22:09:20 2015 +0200
Branches: master
https://developer.blender.org/rB7d10798af22f683a8f55a8c361ad5676bd4160d2

Cycles: Add voxel texture sampler shader node

The idea of this node is to sampling of 3D voxels at a given coordinate
supporting different mapping strategies (world space mapping, object
local space etc).

Currently not in use, it's a preparation step for supporting point density
textures.

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

M	intern/cycles/kernel/CMakeLists.txt
M	intern/cycles/kernel/shaders/CMakeLists.txt
A	intern/cycles/kernel/shaders/node_voxel_texture.osl
M	intern/cycles/kernel/svm/svm.h
M	intern/cycles/kernel/svm/svm_types.h
A	intern/cycles/kernel/svm/svm_voxel.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h

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

diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index d0279b2..b44e917 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -125,6 +125,7 @@ set(SRC_SVM_HEADERS
 	svm/svm_value.h
 	svm/svm_vector_transform.h
 	svm/svm_voronoi.h
+	svm/svm_voxel.h
 	svm/svm_wave.h
 )
 
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index 0b735ed..8193146 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -74,6 +74,7 @@ set(SRC_OSL
 	node_vector_transform.osl
 	node_velvet_bsdf.osl
 	node_voronoi_texture.osl
+	node_voxel_texture.osl
 	node_wavelength.osl
 	node_blackbody.osl
 	node_wave_texture.osl
diff --git a/intern/cycles/kernel/shaders/node_voxel_texture.osl b/intern/cycles/kernel/shaders/node_voxel_texture.osl
new file mode 100644
index 0000000..e45af62
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_voxel_texture.osl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2011-2015 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.
+ */
+
+#include "stdosl.h"
+
+shader node_voxel_texture(
+	string filename = "",
+	string interpolation = "linear",
+	int use_mapping = 0,
+	matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
+	point Vector = P,
+	output float Density = 0,
+	output color Color = 0)
+{
+	point p = Vector;
+	if (use_mapping) {
+		p = transform(mapping, p);
+	}
+	else {
+		p = transform("object", Vector);
+		matrix tfm;
+		if (getattribute("geom:generated_transform", tfm))
+			p = transform(tfm, p);
+	}
+	if(p[0] < 0.0 || p[1] < 0.0 || p[2] < 0.0 ||
+	   p[0] > 1.0 || p[1] > 1.0 || p[2] > 1.0)
+	{
+		Density = 0;
+		Color = color(0, 0, 0);
+	}
+	else {
+		Color = (color)texture3d(filename, p, "wrap", "periodic", "interp", interpolation, "alpha", Density);
+	}
+}
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 15ac651..5ac21e4 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -179,6 +179,7 @@ CCL_NAMESPACE_END
 #include "svm_checker.h"
 #include "svm_brick.h"
 #include "svm_vector_transform.h"
+#include "svm_voxel.h"
 
 CCL_NAMESPACE_BEGIN
 
@@ -446,6 +447,11 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
 				svm_node_blackbody(kg, sd, stack, node.y, node.z);
 				break;
 #  endif  /* __EXTRA_NODES__ */
+#  if NODES_FEATURE(NODE_FEATURE_VOLUME)
+			case NODE_TEX_VOXEL:
+				svm_node_tex_voxel(kg, sd, stack, node, &offset);
+				break;
+#  endif  /* NODES_FEATURE(NODE_FEATURE_VOLUME) */
 #endif  /* NODES_GROUP(NODE_GROUP_LEVEL_3) */
 			case NODE_END:
 				return;
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 009e911..641d30a 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -125,7 +125,8 @@ typedef enum NodeType {
 	NODE_TANGENT,
 	NODE_NORMAL_MAP,
 	NODE_HAIR_INFO,
-	NODE_UVMAP
+	NODE_UVMAP,
+	NODE_TEX_VOXEL,
 } NodeType;
 
 typedef enum NodeAttributeType {
@@ -349,6 +350,11 @@ typedef enum NodeBumpOffset {
 	NODE_BUMP_OFFSET_DY,
 } NodeBumpOffset;
 
+typedef enum NodeTexVoxelSpace {
+	NODE_TEX_VOXEL_SPACE_OBJECT = 0,
+	NODE_TEX_VOXEL_SPACE_WORLD  = 1,
+} NodeTexVoxelSpace;
+
 typedef enum ShaderType {
 	SHADER_TYPE_SURFACE,
 	SHADER_TYPE_VOLUME,
diff --git a/intern/cycles/kernel/svm/svm_voxel.h b/intern/cycles/kernel/svm/svm_voxel.h
new file mode 100644
index 0000000..8752307
--- /dev/null
+++ b/intern/cycles/kernel/svm/svm_voxel.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011-2015 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.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* TODO(sergey): Think of making it more generic volume-type attribute
+ * sampler.
+ */
+ccl_device void svm_node_tex_voxel(KernelGlobals *kg,
+                                   ShaderData *sd,
+                                   float *stack,
+                                   uint4 node,
+                                   int *offset)
+{
+	int id = node.y;
+	uint co_offset, density_out_offset, color_out_offset, space;
+	decode_node_uchar4(node.z, &co_offset, &density_out_offset, &color_out_offset, &space);
+	float3 co = stack_load_float3(stack, co_offset);
+	if(space == NODE_TEX_VOXEL_SPACE_OBJECT) {
+		co = volume_normalized_position(kg, sd, co);
+	}
+	else {
+		kernel_assert(space == NODE_TEX_VOXEL_SPACE_WORLD);
+		Transform tfm;
+		tfm.x = read_node_float(kg, offset);
+		tfm.y = read_node_float(kg, offset);
+		tfm.z = read_node_float(kg, offset);
+		tfm.w = read_node_float(kg, offset);
+		co = transform_point(&tfm, co);
+	}
+	if(co.x < 0.0f || co.y < 0.0f || co.z < 0.0f ||
+	   co.x > 1.0f || co.y > 1.0f || co.z > 1.0f)
+	{
+		if (stack_valid(density_out_offset))
+			stack_store_float(stack, density_out_offset, 0.0f);
+		if (stack_valid(color_out_offset))
+			stack_store_float3(stack, color_out_offset, make_float3(0.0f, 0.0f, 0.0f));
+		return;
+	}
+#ifdef __KERNEL_GPU__
+	float4 r = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+#else
+	float4 r = kernel_tex_image_interp_3d(id, co.x, co.y, co.z);
+#endif
+	if (stack_valid(density_out_offset))
+		stack_store_float(stack, density_out_offset, r.w);
+	if (stack_valid(color_out_offset))
+		stack_store_float3(stack, color_out_offset, make_float3(r.x, r.y, r.z));
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 69ae207..f129654 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1297,6 +1297,158 @@ void BrickTextureNode::compile(OSLCompiler& compiler)
 	compiler.add(this, "node_brick_texture");
 }
 
+/* Point Density Texture */
+
+static ShaderEnum point_density_space_init()
+{
+	ShaderEnum enm;
+
+	enm.insert("Object", NODE_TEX_VOXEL_SPACE_OBJECT);
+	enm.insert("World", NODE_TEX_VOXEL_SPACE_WORLD);
+
+	return enm;
+}
+
+ShaderEnum PointDensityTextureNode::space_enum = point_density_space_init();
+
+PointDensityTextureNode::PointDensityTextureNode()
+: ShaderNode("point_density")
+{
+	image_manager = NULL;
+	slot = -1;
+	filename = "";
+	space = ustring("Object");
+	builtin_data = NULL;
+	interpolation = INTERPOLATION_LINEAR;
+
+	tfm = transform_identity();
+
+	add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::POSITION);
+	add_output("Density", SHADER_SOCKET_FLOAT);
+	add_output("Color", SHADER_SOCKET_COLOR);
+}
+
+PointDensityTextureNode::~PointDensityTextureNode()
+{
+	if(image_manager)
+		image_manager->remove_image(filename, builtin_data, interpolation);
+}
+
+ShaderNode *PointDensityTextureNode::clone() const
+{
+	PointDensityTextureNode *node = new PointDensityTextureNode(*this);
+	node->image_manager = NULL;
+	node->slot = -1;
+	return node;
+}
+
+void PointDensityTextureNode::attributes(Shader *shader,
+                                         AttributeRequestSet *attributes)
+{
+	if(shader->has_volume)
+		attributes->add(ATTR_STD_GENERATED_TRANSFORM);
+
+	ShaderNode::attributes(shader, attributes);
+}
+
+void PointDensityTextureNode::compile(SVMCompiler& compiler)
+{
+	ShaderInput *vector_in = input("Vector");
+	ShaderOutput *density_out = output("Density");
+	ShaderOutput *color_out = output("Color");
+
+	const bool use_density = !density_out->links.empty();
+	const bool use_color = !color_out->links.empty();
+
+	image_manager = compiler.image_manager;
+
+	if (use_density || use_color) {
+		if (use_density)
+			compiler.stack_assign(density_out);
+		if (use_color)
+			compiler.stack_assign(color_out);
+
+		if(slot == -1) {
+			bool is_float, is_linear;
+			slot = image_manager->add_image(filename, builtin_data,
+			                                false, 0,
+			                                is_float, is_linear,
+			                                interpolation,
+			                                true);
+		}
+
+		if(slot != -1) {
+			compiler.stack_assign(vector_in);
+			compiler.add_node(NODE_TEX_VOXEL,
+			                  slot,
+			                  compiler.encode_uchar4(vector_in->stack_offset,
+			                                         density_out->stack_offset,
+			                                         color_out->stack_offset,
+			                                         space_enum[space]));
+			if(space == "World") {
+				compiler.add_node(tfm.x);
+				compiler.add_node(tfm.y);
+				compiler.add_node(tfm.z);
+				compiler.add_node(tfm.w);
+			}
+		}
+		else {
+			compiler.add_node(NODE_VALUE_F,
+			                  __float_as_int(0.0f),
+			                  density_out->stack_offset);
+			compiler.add_node(NODE_VALUE_V, color_out->stack_offset);
+			compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R,
+			                                            TEX_IMAGE_MISSING_G,
+			                                            TEX_IMAGE_MISSING_B));
+		}
+	}
+}
+
+void PointDensityTextureNode::compile(OSLCompiler& compiler)
+{
+	ShaderInput *vector_in = input("Vector");
+	ShaderOutput *density_out = output("Density");
+	ShaderOutput *color_out = output("Color");
+
+	const bool use_density = !density_out->links.empty();
+	const bool use_color = !color_out->links.empty();
+
+	image_manager 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list