[Bf-blender-cvs] [8b54b957f79] cycles_texture_cache: Cycles: ImageTexture node now has dx/dy inputs for offset texture coordinates, being filled out with a hacky shader node duplication a la bump_dx/bump_dy

Stefan Werner noreply at git.blender.org
Mon Nov 27 20:40:19 CET 2017


Commit: 8b54b957f7921a44fea5f9f4f3a5cc1e9620ef9c
Author: Stefan Werner
Date:   Mon May 8 15:12:03 2017 +0200
Branches: cycles_texture_cache
https://developer.blender.org/rB8b54b957f7921a44fea5f9f4f3a5cc1e9620ef9c

Cycles: ImageTexture node now has dx/dy inputs for offset texture coordinates, being filled out with a hacky shader node duplication a la bump_dx/bump_dy

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

M	intern/cycles/graph/node_type.h
M	intern/cycles/kernel/svm/svm.h
M	intern/cycles/kernel/svm/svm_image.h
M	intern/cycles/render/graph.cpp
M	intern/cycles/render/graph.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h

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

diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h
index 7d46e31ce24..035c41cbc2b 100644
--- a/intern/cycles/graph/node_type.h
+++ b/intern/cycles/graph/node_type.h
@@ -78,7 +78,9 @@ struct SocketType
 		LINK_NORMAL            = (1 << 7),
 		LINK_POSITION          = (1 << 8),
 		LINK_TANGENT           = (1 << 9),
-		DEFAULT_LINK_MASK      = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9)
+		LINK_TEXTURE_DX        = (1 << 10),
+		LINK_TEXTURE_DY        = (1 << 11),
+		DEFAULT_LINK_MASK      = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11)
 	};
 
 	ustring name;
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 9ff02c1586b..a6516cd203b 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -272,7 +272,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ccl_a
 #  endif  /* NODES_FEATURE(NODE_FEATURE_BUMP) */
 #  ifdef __TEXTURES__
 			case NODE_TEX_IMAGE:
-				svm_node_tex_image(kg, sd, stack, node);
+				svm_node_tex_image(kg, sd, path_flag, stack, node);
 				break;
 			case NODE_TEX_IMAGE_BOX:
 				svm_node_tex_image_box(kg, sd, stack, node);
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 8d36d7383bb..ccc0a328f2e 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -20,17 +20,28 @@
 
 CCL_NAMESPACE_BEGIN
 
-ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb, uint use_alpha)
+ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, differential ds, differential dt, uint srgb, uint use_alpha, bool fast_lookup)
 {
 	float4 r;
 #  ifdef __OIIO__
 	if(kg->oiio && kg->oiio->tex_paths.size() > id) {
 		OIIO::TextureOpt options;
 		options.swrap = options.twrap = OIIO::TextureOpt::WrapPeriodic;
+#if 0
 		options.interpmode = OIIO::TextureOpt::InterpBilinear;
-		options.mipmode = OIIO::TextureOpt::MipModeOneLevel;
+		options.mipmode = OIIO::TextureOpt::MipModeNoMIP;
+#else
+		if(fast_lookup) {
+			options.interpmode = OIIO::TextureOpt::InterpClosest;
+			options.mipmode = OIIO::TextureOpt::MipModeOneLevel;
+		}
+		else {
+			options.interpmode = OIIO::TextureOpt::InterpSmartBicubic;
+			options.mipmode = OIIO::TextureOpt::MipModeAniso;
+		}
+#endif
 		if(kg->oiio->tex_paths[id]) {
-			bool success = kg->oiio->tex_sys->texture(kg->oiio->tex_paths[id], kg->oiio->tex_sys->get_perthread_info(), options, x, 1.0f - y, 0.0f, 0.0f, 0.0f, 0.0f, 3, (float*)&r);
+			bool success = kg->oiio->tex_sys->texture(kg->oiio->tex_paths[id], kg->oiio->tex_sys->get_perthread_info(), options, x, 1.0f - y, ds.dx, ds.dy, dt.dx, dt.dy, 3, (float*)&r);
 			if(!success) {
 				(void) kg->oiio->tex_sys->geterror();
 			}
@@ -64,28 +75,49 @@ ccl_device_inline float3 texco_remap_square(float3 co)
 	return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
 }
 
-ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
+ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, int path_flag, float *stack, uint4 node)
 {
 	uint id = node.y;
 	uint co_offset, out_offset, alpha_offset, srgb;
+	uint projection, dx_offset, dy_offset;
 
 	decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
+	decode_node_uchar4(node.w, &projection, &dx_offset, &dy_offset, NULL);
 
 	float3 co = stack_load_float3(stack, co_offset);
 	float2 tex_co;
 	uint use_alpha = stack_valid(alpha_offset);
-	if(node.w == NODE_IMAGE_PROJ_SPHERE) {
+	if(projection == NODE_IMAGE_PROJ_SPHERE) {
 		co = texco_remap_square(co);
 		tex_co = map_to_sphere(co);
 	}
-	else if(node.w == NODE_IMAGE_PROJ_TUBE) {
+	else if(projection == NODE_IMAGE_PROJ_TUBE) {
 		co = texco_remap_square(co);
 		tex_co = map_to_tube(co);
 	}
 	else {
 		tex_co = make_float2(co.x, co.y);
 	}
-	float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha);
+
+	bool fast_lookup = path_flag & (PATH_RAY_DIFFUSE | PATH_RAY_SHADOW | PATH_RAY_DIFFUSE_ANCESTOR | PATH_RAY_VOLUME_SCATTER);
+
+	differential ds, dt;
+#ifdef __KERNEL_CPU__
+	if(stack_valid(dx_offset) && stack_valid(dy_offset)) {
+		float3 dx = stack_load_float3(stack, dx_offset);
+		float3 dy = stack_load_float3(stack, dy_offset);
+		ds.dx = fabsf(dx.x - tex_co.x);
+		ds.dy = fabsf(dy.x - tex_co.x);
+		dt.dx = fabsf(dx.y - tex_co.y);
+		dt.dy = fabsf(dy.y - tex_co.y);
+	}
+	else
+#endif
+	{
+		ds = differential_zero();
+		dt = differential_zero();
+	}
+	float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, ds, dt, srgb, use_alpha, fast_lookup);
 
 	if(stack_valid(out_offset))
 		stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
@@ -173,20 +205,22 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float
 	float4 f = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
 	uint use_alpha = stack_valid(alpha_offset);
 
+	differential ds = differential_zero();
+	differential dt = differential_zero();
+
 	/* Map so that no textures are flipped, rotation is somewhat arbitrary. */
 	if(weight.x > 0.0f) {
 		float2 uv = make_float2((signed_N.x < 0.0f)? 1.0f - co.y: co.y, co.z);
-		f += weight.x*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+		f += weight.x*svm_image_texture(kg, id, uv.x, uv.y, ds, dt, srgb, use_alpha, false);
 	}
 	if(weight.y > 0.0f) {
 		float2 uv = make_float2((signed_N.y > 0.0f)? 1.0f - co.x: co.x, co.z);
-		f += weight.y*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+		f += weight.y*svm_image_texture(kg, id, uv.x, uv.y, ds, dt, srgb, use_alpha, false);
 	}
 	if(weight.z > 0.0f) {
 		float2 uv = make_float2((signed_N.z > 0.0f)? 1.0f - co.y: co.y, co.x);
-		f += weight.z*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+		f += weight.z*svm_image_texture(kg, id, uv.x, uv.y, ds, dt, srgb, use_alpha, false);
 	}
-
 	if(stack_valid(out_offset))
 		stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
 	if(stack_valid(alpha_offset))
@@ -212,7 +246,7 @@ ccl_device void svm_node_tex_environment(KernelGlobals *kg, ShaderData *sd, floa
 		uv = direction_to_mirrorball(co);
 
 	uint use_alpha = stack_valid(alpha_offset);
-	float4 f = svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+	float4 f = svm_image_texture(kg, id, uv.x, uv.y, differential_zero(), differential_zero(), srgb, use_alpha, false);
 
 	if(stack_valid(out_offset))
 		stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 08203163d1a..b25b26b8d91 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -304,6 +304,7 @@ void ShaderGraph::simplify(Scene *scene)
 		default_inputs(scene->shader_manager->use_osl());
 		clean(scene);
 		refine_bump_nodes();
+		add_differentials();
 
 		simplified = true;
 	}
@@ -843,6 +844,53 @@ void ShaderGraph::refine_bump_nodes()
 	}
 }
 
+void ShaderGraph::add_differentials()
+{
+	/* we transverse the node graph looking for texture nodes, when we find them,
+	 * we copy the sub-graph defined from "Vector"
+	 * input to the inputs "Vector_dx" and "Vector_dy" */
+	
+	foreach(ShaderNode *node, nodes) {
+		if(node->special_type == SHADER_SPECIAL_TYPE_IMAGE_SLOT && node->input("Vector")->link
+		   && node->input("Vector_dx") && node->input("Vector_dy")) {
+			ShaderInput *vector_input = node->input("Vector");
+			ShaderNodeSet nodes_vector;
+
+			/* make 2 extra copies of the subgraph defined in Vector input */
+			ShaderNodeMap nodes_dx;
+			ShaderNodeMap nodes_dy;
+
+			/* find dependencies for the given input */
+			find_dependencies(nodes_vector, vector_input);
+
+			copy_nodes(nodes_vector, nodes_dx);
+			copy_nodes(nodes_vector, nodes_dy);
+
+			/* mark nodes to indicate they are used for differential computation, so
+			 that any texture coordinates are shifted by dx/dy when sampling */
+			foreach(ShaderNode *node, nodes_vector)
+				node->bump = SHADER_BUMP_CENTER;
+			foreach(NodePair& pair, nodes_dx)
+				pair.second->bump = SHADER_BUMP_DX;
+			foreach(NodePair& pair, nodes_dy)
+				pair.second->bump = SHADER_BUMP_DY;
+
+			ShaderOutput *out = vector_input->link;
+			ShaderOutput *out_dx = nodes_dx[out->parent]->output(out->name());
+			ShaderOutput *out_dy = nodes_dy[out->parent]->output(out->name());
+
+			connect(out_dx, node->input("Vector_dx"));
+			connect(out_dy, node->input("Vector_dy"));
+
+			/* add generated nodes */
+			foreach(NodePair& pair, nodes_dx)
+				add(pair.second);
+			foreach(NodePair& pair, nodes_dy)
+				add(pair.second);
+		}
+	}
+}
+
 void ShaderGraph::bump_from_displacement(bool use_object_space)
 {
 	/* generate bump mapping automatically from displacement. bump mapping is
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 1d1701b30a2..eeb58a2721f 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -276,6 +276,7 @@ protected:
 	void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
 	void bump_from_displacement(bool use_object_space);
 	void refine_bump_nodes();
+	void add_differentials();
 	void default_inputs(bool do_osl);
 	void transform_multi_closure(ShaderNode *node, ShaderOutput *weight_out, bool volume);
 
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 24096907c74..53547bbd6ce 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -240,6 +240,8 @@ NODE_DEFINE(ImageTextureNode)
 	SOCKET_FLOAT(projection_blend, "Projection Blend", 0.0f);
 
 	SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_UV);
+	SOCKET_IN_POINT(vector_dx, "Vector_dx", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_DX);
+	SOCKET_IN_POINT(vector_dy, "Vector_dy", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_DY);
 
 	SOCKET_OUT_COLOR(color, "Color");
 	SOCKET_OUT_FLOAT(alpha, "Alpha");
@@ -299,6 +301,8 @@ void ImageTextureNode::compile(SVMCompiler& compiler)
 	ShaderInput *vector_in = input("Vector");
 	ShaderOutput *color_out = output("Color");
 	ShaderOutput *alpha_out = output("Alpha");
+	Shade

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list