+2

Procedural Brick Shader

Procedural brick shader.

Shader code
/*
	煉瓦シェーダー by あるる(きのもと 結衣) @arlez80
	Brick Shader by Yui Kinomoto

	MIT License
*/
shader_type spatial;

const vec3 MONOCHROME_SCALE = vec3( 0.298912, 0.586611, 0.114478 );

uniform float noise_scale = 700.0;
uniform float brick_shift = 1.6;
uniform float brick_factor = 12.0;
uniform vec2 brick_scale = vec2( 50.0, 100.0 );
uniform vec4 brick_color : hint_color = vec4( 0.7450980392156863, 0.3411764705882353, 0.2196078431372549, 1.0 );
uniform vec4 brick_color2 : hint_color = vec4( 0.37, 0.12, 0.04, 1.0 );
uniform vec4 mortar_joint_color : hint_color = vec4( 1.0, 0.98777, 0.9877777, 1.0 );

vec2 random( vec2 pos )
{ 
	return fract(
		sin(
			vec2(
				dot(pos, vec2(12.9898,78.233))
			,	dot(pos, vec2(-148.998,-65.233))
			)
		) * 43758.5453
	);
}


vec2 value_noise( vec2 pos )
{
	vec2 p = floor( pos );
	vec2 f = fract( pos );

	vec2 v00 = random( p + vec2( 0.0, 0.0 ) );
	vec2 v10 = random( p + vec2( 1.0, 0.0 ) );
	vec2 v01 = random( p + vec2( 0.0, 1.0 ) );
	vec2 v11 = random( p + vec2( 1.0, 1.0 ) );

	vec2 u = f * f * ( 3.0 - 2.0 * f );

	return mix( mix( v00, v10, u.x ), mix( v01, v11, u.x ), u.y );
}

vec3 gen_brick_color( vec2 uv, float noise )
{
	uv.x += float( 0.0 < sin( uv.y ) ) * brick_shift;
	float joint_weight = clamp( abs( sin( uv.y ) ) * abs( sin( uv.x ) ) * brick_factor + random( uv ).x * noise, 0.0, 1.0 );
	float color_select = random( floor( uv / 3.1415926535 ) ).x;

	return mix( mortar_joint_color, mix( brick_color, brick_color2, color_select ), joint_weight ).rgb;
}


vec2 noise_tex( vec2 uv )
{
	return (
		value_noise( uv * 0.984864 ) * 0.5
	+	value_noise( uv * 2.543 ) * 0.25
	+	value_noise( uv * 9.543543 ) * 0.125
	+	value_noise( uv * 21.65436 ) * 0.0625
	+	value_noise( uv * 42.0 ) * 0.03125
	+	value_noise( uv * 87.135148 ) * 0.015625
	+	value_noise( uv * 340.66534654 ) * 0.0078125
	);
}

void fragment( )
{
	vec2 uv = UV * brick_scale;

	float c[9];
	vec2 pixel_size = vec2( 0.1, 0.1 );

	for( int y=0; y<3; y ++ ) {
		for( int x=0; x<3; x ++ ) {
			vec2 v = uv + vec2( float(x-1), float(y-1) ) * pixel_size;
			vec2 nv = UV * noise_scale + vec2( float(x-1), float(y-1) ) * pixel_size;
			c[y*3+x] = length( noise_tex( nv ) ) + dot( gen_brick_color( v, 0.15 ), MONOCHROME_SCALE );
		}
	}

	vec2 sobel_filter = clamp(
		vec2(
			(
				c[0] * -1.0
			+	c[3] * -2.0
			+	c[6] * -1.0
			+	c[2] * 1.0
			+	c[5] * 2.0
			+	c[8] * 1.0
			)
		,	(
				c[0] * -1.0
			+	c[1] * -2.0
			+	c[2] * -1.0
			+	c[6] * 1.0
			+	c[7] * 2.0
			+	c[8] * 1.0
			)
		)
	,	vec2( -1.0, -1.0 )
	,	vec2( 1.0, 1.0 )
	) * 0.5;

	NORMALMAP = normalize( vec3( sobel_filter.x + 0.5, -sobel_filter.y + 0.5, 1.0 ) );
	ALBEDO = gen_brick_color( uv, 0.3 );
	ROUGHNESS = 0.95;
	METALLIC = 0.0;
}
Tags
brick, Procedural
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from arlez80

Sobel with Gaussian filter

Anime-esque Water Shader

CRT shader

Related shaders

Brick/tiled wall

Procedural Illustration-esque Hair Highlight Shader

Procedural Grain Wood Shader

guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
mackatap
mackatap
18 days ago

You are awesome arlez! Thanks for being so generous with your work!