[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44750] trunk/blender: Cycles: support for environment texture "Mirror Ball" projection mode, next to

Brecht Van Lommel brechtvanlommel at pandora.be
Thu Mar 8 20:52:58 CET 2012


Revision: 44750
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44750
Author:   blendix
Date:     2012-03-08 19:52:58 +0000 (Thu, 08 Mar 2012)
Log Message:
-----------
Cycles: support for environment texture "Mirror Ball" projection mode, next to
existing "Equirectangular". This projection is useful to create light probes
from a chrome ball placed in a real scene. It expects as input a photograph of
the chrome ball, cropped so the ball just fits inside the image boundaries.

Example setup with panorama camera and mixing two (poor quality) photographs
from different viewpoints to avoid stretching and hide the photographer:
http://www.pasteall.org/pic/28036

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/blender_shader.cpp
    trunk/blender/intern/cycles/kernel/kernel_montecarlo.h
    trunk/blender/intern/cycles/kernel/svm/svm_image.h
    trunk/blender/intern/cycles/render/nodes.cpp
    trunk/blender/intern/cycles/render/nodes.h
    trunk/blender/intern/cycles/render/svm.cpp
    trunk/blender/intern/cycles/render/svm.h
    trunk/blender/source/blender/editors/space_node/drawnode.c
    trunk/blender/source/blender/makesdna/DNA_node_types.h
    trunk/blender/source/blender/makesrna/intern/rna_nodetree.c
    trunk/blender/source/blender/nodes/shader/nodes/node_shader_tex_environment.c

Modified: trunk/blender/intern/cycles/blender/blender_shader.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_shader.cpp	2012-03-08 18:50:42 UTC (rev 44749)
+++ trunk/blender/intern/cycles/blender/blender_shader.cpp	2012-03-08 19:52:58 UTC (rev 44750)
@@ -332,6 +332,7 @@
 			if(b_image)
 				env->filename = blender_absolute_path(b_data, b_image, b_image.filepath());
 			env->color_space = EnvironmentTextureNode::color_space_enum[(int)b_env_node.color_space()];
+			env->projection = EnvironmentTextureNode::projection_enum[(int)b_env_node.projection()];
 			get_tex_mapping(&env->tex_mapping, b_env_node.texture_mapping());
 			node = env;
 			break;

Modified: trunk/blender/intern/cycles/kernel/kernel_montecarlo.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_montecarlo.h	2012-03-08 18:50:42 UTC (rev 44749)
+++ trunk/blender/intern/cycles/kernel/kernel_montecarlo.h	2012-03-08 19:52:58 UTC (rev 44750)
@@ -224,6 +224,38 @@
 		cos(theta));
 }
 
+/* Mirror Ball <-> Cartesion direction */
+
+__device float3 mirrorball_to_direction(float u, float v)
+{
+	/* point on sphere */
+	float3 dir;
+
+	dir.x = 2.0f*u - 1.0f;
+	dir.z = 2.0f*v - 1.0f;
+	dir.y = -sqrt(max(1.0f - dir.x*dir.x - dir.z*dir.z, 0.0f));
+
+	/* reflection */
+	float3 I = make_float3(0.0f, -1.0f, 0.0f);
+
+	return 2.0f*dot(dir, I)*dir - I;
+}
+
+__device float2 direction_to_mirrorball(float3 dir)
+{
+	/* inverse of mirrorball_to_direction */
+	dir.y -= 1.0f;
+
+	float div = 2.0f*sqrt(max(-0.5f*dir.y, 0.0f));
+	if(div > 0.0f)
+		dir /= div;
+
+	float u = 0.5f*(dir.x + 1.0f);
+	float v = 0.5f*(dir.z + 1.0f);
+
+	return make_float2(u, v);
+}
+
 CCL_NAMESPACE_END
 
 #endif /* __KERNEL_MONTECARLO_CL__ */

Modified: trunk/blender/intern/cycles/kernel/svm/svm_image.h
===================================================================
--- trunk/blender/intern/cycles/kernel/svm/svm_image.h	2012-03-08 18:50:42 UTC (rev 44749)
+++ trunk/blender/intern/cycles/kernel/svm/svm_image.h	2012-03-08 19:52:58 UTC (rev 44750)
@@ -171,11 +171,20 @@
 {
 	uint id = node.y;
 	uint co_offset, out_offset, alpha_offset, srgb;
+	uint projection = node.w;
 
 	decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
 
 	float3 co = stack_load_float3(stack, co_offset);
-	float2 uv = direction_to_equirectangular(co);
+	float2 uv;
+
+	co = normalize(co);
+	
+	if(projection == 0)
+		uv = direction_to_equirectangular(co);
+	else
+		uv = direction_to_mirrorball(co);
+
 	float4 f = svm_image_texture(kg, id, uv.x, uv.y);
 	float3 r = make_float3(f.x, f.y, f.z);
 

Modified: trunk/blender/intern/cycles/render/nodes.cpp
===================================================================
--- trunk/blender/intern/cycles/render/nodes.cpp	2012-03-08 18:50:42 UTC (rev 44749)
+++ trunk/blender/intern/cycles/render/nodes.cpp	2012-03-08 19:52:58 UTC (rev 44750)
@@ -146,19 +146,26 @@
 		compiler.stack_assign(alpha_out);
 
 	if(slot != -1) {
-		int srgb = (is_float || color_space != "Color")? 0: 1;
 		compiler.stack_assign(vector_in);
 
-		if(!tex_mapping.skip())
-			tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
+		int srgb = (is_float || color_space != "Color")? 0: 1;
+		int vector_offset = vector_in->stack_offset;
 
+		if(!tex_mapping.skip()) {
+			vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR);
+			tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset);
+		}
+
 		compiler.add_node(NODE_TEX_IMAGE,
 			slot,
 			compiler.encode_uchar4(
-				vector_in->stack_offset,
+				vector_offset,
 				color_out->stack_offset,
 				alpha_out->stack_offset,
 				srgb));
+	
+		if(vector_offset != vector_in->stack_offset)
+			compiler.stack_clear_offset(vector_in->type, vector_offset);
 	}
 	else {
 		/* image not found */
@@ -183,7 +190,18 @@
 
 /* Environment Texture */
 
+static ShaderEnum projection_init()
+{
+	ShaderEnum enm;
+
+	enm.insert("Equirectangular", 0);
+	enm.insert("Mirror Ball", 1);
+
+	return enm;
+}
+
 ShaderEnum EnvironmentTextureNode::color_space_enum = color_space_init();
+ShaderEnum EnvironmentTextureNode::projection_enum = projection_init();
 
 EnvironmentTextureNode::EnvironmentTextureNode()
 : TextureNode("environment_texture")
@@ -193,6 +211,7 @@
 	is_float = false;
 	filename = "";
 	color_space = ustring("Color");
+	projection = ustring("Equirectangular");
 
 	add_input("Vector", SHADER_SOCKET_VECTOR, ShaderInput::POSITION);
 	add_output("Color", SHADER_SOCKET_COLOR);
@@ -228,22 +247,29 @@
 		compiler.stack_assign(color_out);
 	if(!alpha_out->links.empty())
 		compiler.stack_assign(alpha_out);
+	
+	if(slot != -1) {
+		compiler.stack_assign(vector_in);
 
-	if(slot != -1) {
 		int srgb = (is_float || color_space != "Color")? 0: 1;
+		int vector_offset = vector_in->stack_offset;
 
-		compiler.stack_assign(vector_in);
+		if(!tex_mapping.skip()) {
+			vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR);
+			tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset);
+		}
 
-		if(!tex_mapping.skip())
-			tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
-
 		compiler.add_node(NODE_TEX_ENVIRONMENT,
 			slot,
 			compiler.encode_uchar4(
-				vector_in->stack_offset,
+				vector_offset,
 				color_out->stack_offset,
 				alpha_out->stack_offset,
-				srgb));
+				srgb),
+			projection_enum[projection]);
+	
+		if(vector_offset != vector_in->stack_offset)
+			compiler.stack_clear_offset(vector_in->type, vector_offset);
 	}
 	else {
 		/* image not found */
@@ -351,11 +377,19 @@
 
 	if(vector_in->link)
 		compiler.stack_assign(vector_in);
-	if(!tex_mapping.skip())
-		tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
 
+	int vector_offset = vector_in->stack_offset;
+
+	if(!tex_mapping.skip()) {
+		vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR);
+		tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset);
+	}
+
 	compiler.stack_assign(color_out);
-	compiler.add_node(NODE_TEX_SKY, vector_in->stack_offset, color_out->stack_offset);
+	compiler.add_node(NODE_TEX_SKY, vector_offset, color_out->stack_offset);
+
+	if(vector_offset != vector_in->stack_offset)
+		compiler.stack_clear_offset(vector_in->type, vector_offset);
 }
 
 void SkyTextureNode::compile(OSLCompiler& compiler)
@@ -402,16 +436,23 @@
 
 	if(vector_in->link) compiler.stack_assign(vector_in);
 
-	if(!tex_mapping.skip())
-		tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
+	int vector_offset = vector_in->stack_offset;
 
+	if(!tex_mapping.skip()) {
+		vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR);
+		tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset);
+	}
+
 	if(!fac_out->links.empty())
 		compiler.stack_assign(fac_out);
 	if(!color_out->links.empty())
 		compiler.stack_assign(color_out);
 
 	compiler.add_node(NODE_TEX_GRADIENT,
-		compiler.encode_uchar4(type_enum[type], vector_in->stack_offset, fac_out->stack_offset, color_out->stack_offset));
+		compiler.encode_uchar4(type_enum[type], vector_offset, fac_out->stack_offset, color_out->stack_offset));
+
+	if(vector_offset != vector_in->stack_offset)
+		compiler.stack_clear_offset(vector_in->type, vector_offset);
 }
 
 void GradientTextureNode::compile(OSLCompiler& compiler)
@@ -448,21 +489,28 @@
 	if(detail_in->link) compiler.stack_assign(detail_in);
 	if(distortion_in->link) compiler.stack_assign(distortion_in);
 
-	if(!tex_mapping.skip())
-		tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
+	int vector_offset = vector_in->stack_offset;
 
+	if(!tex_mapping.skip()) {
+		vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR);
+		tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset);
+	}
+
 	if(!fac_out->links.empty())
 		compiler.stack_assign(fac_out);
 	if(!color_out->links.empty())
 		compiler.stack_assign(color_out);
 
 	compiler.add_node(NODE_TEX_NOISE,
-		compiler.encode_uchar4(vector_in->stack_offset, scale_in->stack_offset, detail_in->stack_offset, distortion_in->stack_offset),
+		compiler.encode_uchar4(vector_offset, scale_in->stack_offset, detail_in->stack_offset, distortion_in->stack_offset),
 		compiler.encode_uchar4(color_out->stack_offset, fac_out->stack_offset));
 	compiler.add_node(
 		__float_as_int(scale_in->value.x),
 		__float_as_int(detail_in->value.x),
 		__float_as_int(distortion_in->value.x));
+
+	if(vector_offset != vector_in->stack_offset)
+		compiler.stack_clear_offset(vector_in->type, vector_offset);
 }
 
 void NoiseTextureNode::compile(OSLCompiler& compiler)
@@ -506,16 +554,23 @@
 	if(vector_in->link) compiler.stack_assign(vector_in);
 	if(scale_in->link) compiler.stack_assign(scale_in);
 
-	if(!tex_mapping.skip())
-		tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
+	int vector_offset = vector_in->stack_offset;
 
+	if(!tex_mapping.skip()) {
+		vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR);
+		tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset);
+	}
+
 	compiler.stack_assign(color_out);
 	compiler.stack_assign(fac_out);
 
 	compiler.add_node(NODE_TEX_VORONOI,
 		coloring_enum[coloring],
-		compiler.encode_uchar4(scale_in->stack_offset, vector_in->stack_offset, fac_out->stack_offset, color_out->stack_offset),
+		compiler.encode_uchar4(scale_in->stack_offset, vector_offset, fac_out->stack_offset, color_out->stack_offset),
 		__float_as_int(scale_in->value.x));
+
+	if(vector_offset != vector_in->stack_offset)
+		compiler.stack_clear_offset(vector_in->type, vector_offset);
 }
 
 void VoronoiTextureNode::compile(OSLCompiler& compiler)
@@ -578,16 +633,20 @@
 	if(gain_in->link) compiler.stack_assign(gain_in);
 	if(scale_in->link) compiler.stack_assign(scale_in);
 
-	if(!tex_mapping.skip())
-		tex_mapping.compile(compiler, vector_in->stack_offset, vector_in->stack_offset);
+	int vector_offset = vector_in->stack_offset;
 
+	if(!tex_mapping.skip()) {
+		vector_offset = compiler.stack_find_offset(SHADER_SOCKET_VECTOR);
+		tex_mapping.compile(compiler, vector_in->stack_offset, vector_offset);
+	}
+
 	if(!fac_out->links.empty())
 		compiler.stack_assign(fac_out);
 	if(!color_out->links.empty())
 		compiler.stack_assign(color_out);
 
 	compiler.add_node(NODE_TEX_MUSGRAVE,
-		compiler.encode_uchar4(type_enum[type], vector_in->stack_offset, color_out->stack_offset, fac_out->stack_offset),

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list