[Bf-blender-cvs] [b2974d7] master: Cycles: Add smoothing option to the Brick Texture

Lukas Stockner noreply at git.blender.org
Sun Oct 30 02:31:01 CEST 2016


Commit: b2974d7ab79a257f8628c24c05d43da25791018d
Author: Lukas Stockner
Date:   Sun Oct 30 01:33:10 2016 +0200
Branches: master
https://developer.blender.org/rBb2974d7ab79a257f8628c24c05d43da25791018d

Cycles: Add smoothing option to the Brick Texture

This option allows to create a smoother transition between Bricks and Mortar - 0 applies no smoothing, and 1 smooths across the whole mortar width.
Mainly useful for displacement textures.

The new default value for the smoothing option is 0.1 to give some smoothing that helps with antialiasing, but existing nodes are loaded with smoothing 0 to preserve compatibility.

Reviewers: sergey, dingto, juicyfruit, brecht

Reviewed By: brecht

Subscribers: Blendify, nutel

Differential Revision: https://developer.blender.org/D2230

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

M	intern/cycles/kernel/shaders/node_brick_texture.osl
M	intern/cycles/kernel/svm/svm_brick.h
M	intern/cycles/render/nodes.cpp
M	intern/cycles/render/nodes.h
M	source/blender/nodes/shader/nodes/node_shader_tex_brick.c

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

diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl
index d5e0a7d..c303594 100644
--- a/intern/cycles/kernel/shaders/node_brick_texture.osl
+++ b/intern/cycles/kernel/shaders/node_brick_texture.osl
@@ -28,7 +28,7 @@ float brick_noise(int n) /* fast integer noise */
 	return 0.5 * ((float)nn / 1073741824.0);
 }
 
-float brick(point p, float mortar_size, float bias,
+float brick(point p, float mortar_size, float mortar_smooth, float bias,
 	float BrickWidth, float row_height, float offset_amount, int offset_frequency,
 	float squash_amount, int squash_frequency, float tint)
 {
@@ -51,9 +51,17 @@ float brick(point p, float mortar_size, float bias,
 
 	tint = clamp((brick_noise((rownum << 16) + (bricknum & 65535)) + bias), 0.0, 1.0);
 
-	return (x < mortar_size || y < mortar_size ||
-	        x > (brick_width - mortar_size) ||
-	        y > (row_height - mortar_size)) ? 1.0 : 0.0;
+	float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
+	if(min_dist >= mortar_size) {
+		return 0.0;
+	}
+	else if(mortar_smooth == 0.0) {
+		return 1.0;
+	}
+	else {
+		min_dist = 1.0 - min_dist/mortar_size;
+		return smoothstep(0.0, mortar_smooth, min_dist);
+	}
 }
 
 shader node_brick_texture(
@@ -69,6 +77,7 @@ shader node_brick_texture(
 	color Mortar = 0.0,
 	float Scale = 5.0,
 	float MortarSize = 0.02,
+	float MortarSmooth = 0.0,
 	float Bias = 0.0,
 	float BrickWidth = 0.5,
 	float RowHeight = 0.25,
@@ -83,7 +92,7 @@ shader node_brick_texture(
 	float tint = 0.0;
 	color Col = Color1;
 	
-	Fac = brick(p * Scale, MortarSize, Bias, BrickWidth, RowHeight,
+	Fac = brick(p * Scale, MortarSize, MortarSmooth, Bias, BrickWidth, RowHeight,
 		offset, offset_frequency, squash, squash_frequency, tint);
 		
 	if (Fac != 1.0) {
@@ -91,6 +100,6 @@ shader node_brick_texture(
 		Col = facm * Color1 + tint * Color2;
 	}
 	
-	Color = (Fac == 1.0) ? Mortar : Col;
+	Color = mix(Col, Mortar, Fac);
 }
 
diff --git a/intern/cycles/kernel/svm/svm_brick.h b/intern/cycles/kernel/svm/svm_brick.h
index 9b0cf5a..47e1ba2 100644
--- a/intern/cycles/kernel/svm/svm_brick.h
+++ b/intern/cycles/kernel/svm/svm_brick.h
@@ -27,7 +27,7 @@ ccl_device_noinline float brick_noise(int n) /* fast integer noise */
 	return 0.5f * ((float)nn / 1073741824.0f);
 }
 
-ccl_device_noinline float2 svm_brick(float3 p, float mortar_size, float bias,
+ccl_device_noinline float2 svm_brick(float3 p, float mortar_size, float mortar_smooth, float bias,
 	float brick_width, float row_height, float offset_amount, int offset_frequency,
 	float squash_amount, int squash_frequency)
 {
@@ -47,30 +47,41 @@ ccl_device_noinline float2 svm_brick(float3 p, float mortar_size, float bias,
 	x = (p.x+offset) - brick_width*bricknum;
 	y = p.y - row_height*rownum;
 
-	return make_float2(
-		saturate((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias)),
+	float tint = saturate((brick_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias));
+	float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
 
-		(x < mortar_size || y < mortar_size ||
-		x > (brick_width - mortar_size) ||
-		y > (row_height - mortar_size)) ? 1.0f : 0.0f);
+	float mortar;
+	if(min_dist >= mortar_size) {
+		mortar = 0.0f;
+	}
+	else if(mortar_smooth == 0.0f) {
+		mortar = 1.0f;
+	}
+	else {
+		min_dist = 1.0f - min_dist/mortar_size;
+		mortar = (min_dist < mortar_smooth)? smoothstepf(min_dist / mortar_smooth) : 1.0f;
+	}
+
+	return make_float2(tint, mortar);
 }
 
 ccl_device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
 {	
 	uint4 node2 = read_node(kg, offset);
 	uint4 node3 = read_node(kg, offset);
+	uint4 node4 = read_node(kg, offset);
 	
 	/* Input and Output Sockets */
 	uint co_offset, color1_offset, color2_offset, mortar_offset, scale_offset;
 	uint mortar_size_offset, bias_offset, brick_width_offset, row_height_offset;
-	uint color_offset, fac_offset;
+	uint color_offset, fac_offset, mortar_smooth_offset;
 	
 	/* RNA properties */
 	uint offset_frequency, squash_frequency;
 	
 	decode_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &mortar_offset);
 	decode_node_uchar4(node.z, &scale_offset, &mortar_size_offset, &bias_offset, &brick_width_offset);
-	decode_node_uchar4(node.w, &row_height_offset, &color_offset, &fac_offset, NULL);
+	decode_node_uchar4(node.w, &row_height_offset, &color_offset, &fac_offset, &mortar_smooth_offset);
 	
 	decode_node_uchar4(node2.x, &offset_frequency, &squash_frequency, NULL, NULL);
 
@@ -82,13 +93,14 @@ ccl_device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *sta
 	
 	float scale = stack_load_float_default(stack, scale_offset, node2.y);
 	float mortar_size = stack_load_float_default(stack, mortar_size_offset, node2.z);
+	float mortar_smooth = stack_load_float_default(stack, mortar_smooth_offset, node4.x);
 	float bias = stack_load_float_default(stack, bias_offset, node2.w);
 	float brick_width = stack_load_float_default(stack, brick_width_offset, node3.x);
 	float row_height = stack_load_float_default(stack, row_height_offset, node3.y);
 	float offset_amount = __int_as_float(node3.z);
 	float squash_amount = __int_as_float(node3.w);
 	
-	float2 f2 = svm_brick(co*scale, mortar_size, bias, brick_width, row_height,
+	float2 f2 = svm_brick(co*scale, mortar_size, mortar_smooth, bias, brick_width, row_height,
 		offset_amount, offset_frequency, squash_amount, squash_frequency);
 
 	float tint = f2.x;
@@ -100,7 +112,7 @@ ccl_device void svm_node_tex_brick(KernelGlobals *kg, ShaderData *sd, float *sta
 	}
 
 	if(stack_valid(color_offset))
-		stack_store_float3(stack, color_offset, (f == 1.0f)? mortar: color1);
+		stack_store_float3(stack, color_offset, lerp(color1, mortar, f));
 	if(stack_valid(fac_offset))
 		stack_store_float(stack, fac_offset, f);
 }
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 3b4aa38..f293af3 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1257,6 +1257,7 @@ NODE_DEFINE(BrickTextureNode)
 	SOCKET_IN_COLOR(mortar, "Mortar", make_float3(0.0f, 0.0f, 0.0f));
 	SOCKET_IN_FLOAT(scale, "Scale", 5.0f);
 	SOCKET_IN_FLOAT(mortar_size, "Mortar Size", 0.02f);
+	SOCKET_IN_FLOAT(mortar_smooth, "Mortar Smooth", 0.0f);
 	SOCKET_IN_FLOAT(bias, "Bias", 0.0f);
 	SOCKET_IN_FLOAT(brick_width, "Brick Width", 0.5f);
 	SOCKET_IN_FLOAT(row_height, "Row Height", 0.25f);
@@ -1280,6 +1281,7 @@ void BrickTextureNode::compile(SVMCompiler& compiler)
 	ShaderInput *mortar_in = input("Mortar");
 	ShaderInput *scale_in = input("Scale");
 	ShaderInput *mortar_size_in = input("Mortar Size");
+	ShaderInput *mortar_smooth_in = input("Mortar Smooth");
 	ShaderInput *bias_in = input("Bias");
 	ShaderInput *brick_width_in = input("Brick Width");
 	ShaderInput *row_height_in = input("Row Height");
@@ -1303,7 +1305,8 @@ void BrickTextureNode::compile(SVMCompiler& compiler)
 		compiler.encode_uchar4(
 			compiler.stack_assign_if_linked(row_height_in),
 			compiler.stack_assign_if_linked(color_out),
-			compiler.stack_assign_if_linked(fac_out)));
+			compiler.stack_assign_if_linked(fac_out),
+			compiler.stack_assign_if_linked(mortar_smooth_in)));
 			
 	compiler.add_node(compiler.encode_uchar4(offset_frequency, squash_frequency),
 		__float_as_int(scale),
@@ -1315,6 +1318,11 @@ void BrickTextureNode::compile(SVMCompiler& compiler)
 		__float_as_int(offset),
 		__float_as_int(squash));
 
+	compiler.add_node(__float_as_int(mortar_smooth),
+		SVM_STACK_INVALID,
+		SVM_STACK_INVALID,
+		SVM_STACK_INVALID);
+
 	tex_mapping.compile_end(compiler, vector_in, vector_offset);
 }
 
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 13791c6..eb0f797 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -243,7 +243,7 @@ public:
 	int offset_frequency, squash_frequency;
 
 	float3 color1, color2, mortar;
-	float scale, mortar_size, bias, brick_width, row_height;
+	float scale, mortar_size, mortar_smooth, bias, brick_width, row_height;
 	float3 vector;
 
 	virtual int get_group() { return NODE_GROUP_LEVEL_2; }
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
index bb7f216..0be47c4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.c
@@ -36,6 +36,7 @@ static bNodeSocketTemplate sh_node_tex_brick_in[] = {
 	{ 	SOCK_RGBA, 1, 	N_("Mortar"), 		0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
 	{	SOCK_FLOAT, 1,  N_("Scale"),		5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
 	{	SOCK_FLOAT, 1,  N_("Mortar Size"),	0.02f, 0.0f, 0.0f, 0.0f, 0.0f, 0.125f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
+	{	SOCK_FLOAT, 1,  N_("Mortar Smooth"),	0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
 	{	SOCK_FLOAT, 1,  N_("Bias"),		    0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
 	{	SOCK_FLOAT, 1,  N_("Brick Width"),	0.5f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
 	{	SOCK_FLOAT, 1,  N_("Row Height"),   0.25f, 0.0f, 0.0f, 0.0f, 0.01f, 100.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK},
@@ -60,6 +61,12 @@ static void node_shader_init_tex_brick(bNodeTree *UNUSED(ntree), bNode *node)
 	tex->squash_freq = 2;
 
 	node->storage = tex;
+
+	for (bNodeSocket *sock = node->inputs.first; sock; sock = sock->next) {
+		if (STREQ(sock->name, "Mortar Smooth")) {
+			((bNodeSocketValueFloat*)sock->default_value)->value = 0.1f;
+		}
+	}
 }
 
 static int node_shader_gpu_tex_brick(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)




More information about the Bf-blender-cvs mailing list