[Bf-blender-cvs] [f48e3cf] cycles_point_density: Color support for point density texture in Cycles.

Lukas Tönne noreply at git.blender.org
Fri Apr 3 19:51:21 CEST 2015


Commit: f48e3cf6bf1f47b522d437c48bed570e499d46e2
Author: Lukas Tönne
Date:   Fri Apr 3 19:49:02 2015 +0200
Branches: cycles_point_density
https://developer.blender.org/rBf48e3cf6bf1f47b522d437c48bed570e499d46e2

Color support for point density texture in Cycles.

This extends the point density evaluation to also store RGB color values
in the array provided by Cycles.

Since internally all Cycles textures are 4-float RGBA textures anyway,
it does not make a lot of sense to store density and color separately.
This could eventually be preferable to avoid unnecessary storage.

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

M	intern/cycles/blender/blender_session.cpp
M	intern/cycles/kernel/svm/svm_voxel.h
M	intern/cycles/render/nodes.cpp
M	source/blender/editors/space_node/drawnode.c
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/shader/nodes/node_shader_tex_pointdensity.c
M	source/blender/render/intern/source/pointdensity.c

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

diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index e57ffa4..8832c60 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -988,7 +988,7 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti
 		BL::Node b_node(ptr);
 		if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
 			BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
-			channels = 1;
+			channels = 4;
 			width = height = depth = b_point_density_node.resolution();
 			is_float = true;
 		}
diff --git a/intern/cycles/kernel/svm/svm_voxel.h b/intern/cycles/kernel/svm/svm_voxel.h
index 46d2a7b..4838926 100644
--- a/intern/cycles/kernel/svm/svm_voxel.h
+++ b/intern/cycles/kernel/svm/svm_voxel.h
@@ -23,8 +23,8 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg,
                                    int *offset)
 {
 	int id = node.y;
-	uint co_offset, out_offset, space;
-	decode_node_uchar4(node.z, &co_offset, &out_offset, &space, NULL);
+	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);
@@ -41,7 +41,10 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg,
 	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)
 	{
-		stack_store_float(stack, out_offset, 0.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__
@@ -49,8 +52,10 @@ ccl_device void svm_node_tex_voxel(KernelGlobals *kg,
 #else
 	float4 r = kernel_tex_image_interp_3d(id, co.x, co.y, co.z);
 #endif
-	float3 f = float4_to_float3(r);
-	stack_store_float(stack, out_offset, average(f));
+	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 9bec423..c04e544b 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1325,6 +1325,7 @@ PointDensityTextureNode::PointDensityTextureNode()
 
 	add_input("Vector", SHADER_SOCKET_POINT, ShaderInput::POSITION);
 	add_output("Density", SHADER_SOCKET_FLOAT);
+	add_output("Color", SHADER_SOCKET_COLOR);
 }
 
 PointDensityTextureNode::~PointDensityTextureNode()
@@ -1354,43 +1355,52 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler)
 {
 	ShaderInput *vector_in = input("Vector");
 	ShaderOutput *density_out = output("Density");
+	ShaderOutput *color_out = output("Color");
 
-	if(density_out->links.empty()) {
-		return;
-	}
+	bool use_density = !density_out->links.empty();
+	bool use_color = !color_out->links.empty();
 
 	image_manager = compiler.image_manager;
 
-	compiler.stack_assign(density_out);
+	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,
-		                                false);
-	}
+		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,
-		                                         space_enum[space],
-		                                         0));
-		if(space == "World") {
-			compiler.add_node(tfm.x);
-			compiler.add_node(tfm.y);
-			compiler.add_node(tfm.z);
-			compiler.add_node(tfm.w);
+		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));
 		}
-	}
-	else {
-		compiler.add_node(NODE_VALUE_F,
-		                  __float_as_int(0.0f),
-		                  density_out->stack_offset);
 	}
 }
 
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 77653cd..b37f42b 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -952,6 +952,7 @@ static void node_shader_buts_tex_pointdensity(uiLayout *layout, bContext *UNUSED
 	uiItemR(layout, ptr, "radius", 0, NULL, ICON_NONE);
 	uiItemR(layout, ptr, "interpolation", 0, NULL, ICON_NONE);
 	uiItemR(layout, ptr, "resolution", 0, NULL, ICON_NONE);
+	uiItemR(layout, ptr, "color_source", 0, NULL, ICON_NONE);
 }
 
 static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index bc657ce..911c6ed 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -795,6 +795,8 @@ typedef struct NodeShaderTexPointDensity {
 	int resolution;
 	short space;
 	short interpolation;
+	short color_source;
+	short pad2;
 } NodeShaderTexPointDensity;
 
 /* TEX_output */
@@ -1111,4 +1113,11 @@ enum {
 	SHD_POINTDENSITY_SPACE_WORLD  = 1,
 };
 
+enum {
+	SHD_POINTDENSITY_COLOR_CONSTANT     = 0,
+	SHD_POINTDENSITY_COLOR_PARTAGE      = 1,
+	SHD_POINTDENSITY_COLOR_PARTSPEED    = 2,
+	SHD_POINTDENSITY_COLOR_PARTVEL      = 3,
+};
+
 #endif
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 8436424..c3b9280 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -2933,23 +2933,34 @@ static void rna_ShaderNodePointDensity_psys_set(PointerRNA *ptr, PointerRNA valu
 	}
 }
 
+static int point_density_color_source_from_shader(NodeShaderTexPointDensity *shader_point_density)
+{
+	switch (shader_point_density->color_source) {
+		case SHD_POINTDENSITY_COLOR_CONSTANT: return TEX_PD_COLOR_CONSTANT;
+		case SHD_POINTDENSITY_COLOR_PARTAGE: return TEX_PD_COLOR_PARTAGE;
+		case SHD_POINTDENSITY_COLOR_PARTSPEED: return TEX_PD_COLOR_PARTSPEED;
+		case SHD_POINTDENSITY_COLOR_PARTVEL: return TEX_PD_COLOR_PARTVEL;
+		default: BLI_assert(false); return TEX_PD_COLOR_CONSTANT;
+	}
+}
+
 /* TODO(sergey): This functio nassumes allocated array was passed,
  * works fine with Cycles via C++ RNA, but fails with call from python.
  */
-void rna_ShaderNodePointDensity_density_calc(bNode *self, Scene *scene, int *length, float **density)
+void rna_ShaderNodePointDensity_density_calc(bNode *self, Scene *scene, int *length, float **values)
 {
 	NodeShaderTexPointDensity *shader_point_density = self->storage;
 	PointDensity pd;
 
-	*length = shader_point_density->resolution *
-	          shader_point_density->resolution *
-	          shader_point_density->resolution;
+	*length = 4 * shader_point_density->resolution *
+	              shader_point_density->resolution *
+	              shader_point_density->resolution;
 
-	if (*density == NULL) {
-		*density = MEM_mallocN(sizeof(float) * (*length), "density dynamic array");
+	if (*values == NULL) {
+		*values = MEM_mallocN(sizeof(float) * (*length), "point density dynamic array");
 	}
 
-	/* Cretae PointDensity structure from node for sampling. */
+	/* Create PointDensity structure from node for sampling. */
 	BKE_texture_pointdensity_init_data(&pd);
 	pd.object = (Object *)self->id;
 	pd.radius = shader_point_density->radius;
@@ -2963,11 +2974,12 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self, Scene *scene, int *len
 		pd.source = TEX_PD_OBJECT;
 		pd.ob_cache_space = TEX_PD_OBJECTSPACE;
 	}
+	pd.color_source = point_density_color_source_from_shader(shader_point_density);
 
 	/* Single-threaded sampling of the voxel domain. */
 	RE_sample_point_density(scene, &pd,
 	                        shader_point_density->resolution,
-	                        *density);
+	                        *values);
 
 	/* We're done, time to clean up. */
 	BKE_texture_pointdensity_free_data(&pd);
@@ -3817,6 +3829,17 @@ static void def_sh_tex_pointdensity(StructRNA *srna)
 		{0, NULL, 0, NULL, NULL}
 	};
 
+	static EnumPropertyItem color_source_items[] = {
+		{SHD_POINTDENSITY_COLOR_CONSTANT, "CONSTANT", 0, "Constant", ""},
+		{SHD_POINTDENSITY_COLOR_PARTAGE, "PARTICLE_AGE", 0, "Particle Age",
+		                                 "Lifetime mapped as 0.0 - 1.0 intensity"},
+		{SHD_POINTDENSITY_COLOR_PARTSPEED, "PARTICLE_SPEED", 0, "Particle Speed",
+		                                   "Particle speed (absolute magnitude of velocity) mapped as 0.0-1.0 intensity"},
+		{SHD_POINTDENSITY_COLOR_PARTV

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list