{
	"name": "skewed_uneven_bricks",
	"node_position": {
		"x": 0,
		"y": 0
	},
	"parameters": {
		"bevel": 0.1,
		"columns": 6,
		"corner": 0.3,
		"mortar": 0.1,
		"randomness": 1,
		"round": 0,
		"rows": 6
	},
	"seed_int": 0,
	"shader_model": {
		"code": [
			"vec3 $(name_uv)_brick_uv;",
			"vec3 $(name_uv)_corner_uv;",
			"vec4 $(name_uv)_brick_fill;",
			"vec4 $(name_uv)_corner_fill;",
			"float $(name_uv)_bricks = skewed_uneven_bricks($uv, vec2($columns, $rows), $randomness, $mortar * $mortar_map($uv), $bevel * $bevel_map($uv), $round * $round_map($uv), $corner, $seed, $(name_uv)_brick_uv, $(name_uv)_corner_uv, $(name_uv)_brick_fill, $(name_uv)_corner_fill);"
		],
		"global": [
			"vec4 generate_rect(vec2 a, vec2 b, vec2 c, vec2 d) {",
			"\tvec2 start = min(min(a, b), min(c, d));",
			"\tvec2 end = max(max(a, b), max(c, d));",
			"\treturn vec4(start, end);",
			"}",
			"",
			"float cross2d( in vec2 a, in vec2 b ) { return a.x*b.y - a.y*b.x; }",
			"",
			"vec2 invBilinear( in vec2 p, in vec2 a, in vec2 b, in vec2 c, in vec2 d )",
			"{",
			"\tvec2 res = vec2(-1.0);",
			"",
			"\tvec2 e = b-a;",
			"\tvec2 f = d-a;",
			"\tvec2 g = a-b+c-d;",
			"\tvec2 h = p-a;",
			"\t\t",
			"\tfloat k2 = cross2d( g, f );",
			"\tfloat k1 = cross2d( e, f ) + cross2d( h, g );",
			"\tfloat k0 = cross2d( h, e );",
			"\tk2 /= k0; k1 /= k0; k0 = 1.0;",
			"\t",
			"\t// if edges are parallel, this is a linear equation",
			"\tif( abs(k2)<0.001 )",
			"\t{",
			"\t\tres = vec2( (h.x*k1+f.x*k0)/(e.x*k1-g.x*k0), -k0/k1 );",
			"\t}",
			"\t// otherwise, it's a quadratic",
			"\telse",
			"\t{",
			"\t\tfloat w = k1*k1 - 4.0*k0*k2;",
			"\t\tif( w<0.0 ) return vec2(-1.0);",
			"\t\tw = sqrt( w );",
			"",
			"\t\tfloat ik2 = 0.5/k2;",
			"\t\tfloat v = (-k1 - w)*ik2;",
			"\t\tfloat u = (h.x - f.x*v)/(e.x + g.x*v);",
			"\t\t",
			"\t\tif( u<0.0 || u>1.0 || v<0.0 || v>1.0 )",
			"\t\t{",
			"\t\t   v = (-k1 + w)*ik2;",
			"\t\t   u = (h.x - f.x*v)/(e.x + g.x*v);",
			"\t\t}",
			"\t\tres = vec2( u, v );",
			"\t}",
			"\t",
			"\treturn res;",
			"}",
			"",
			"bool point_left_of_line(vec4 line, vec2 c) {",
			"\tvec2 a = line.xy;",
			"\tvec2 b = line.zw;",
			"\treturn ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)) > 0.0;",
			"}",
			"",
			"vec2 skewed_uneven_cut(vec2 x, vec2 size, float randomness) {",
			"\tconst float grid_size = 4096.0;",
			"\treturn 0.5 + (rand2(round(mod(x, size)*grid_size)/grid_size) - 0.5) * randomness;",
			"}",
			"",
			"float skewed_uneven_bricks(vec2 uv, vec2 size, float randomness, float mortar, float bevel, float round_radius, float corner, float seed, out vec3 brick_uv, out vec3 corner_uv, out vec4 brick_fill, out vec4 corner_fill) {",
			"\tconst float grid_size = 4096.0;",
			"\t",
			"\t// Algorithm messes up at randomness 0.0",
			"\trandomness = abs(randomness) < 0.001 ? 0.001 : randomness;",
			"\t",
			"\tuv = fract(uv);",
			"\tvec2 scaled_uv = uv * size;",
			"\t",
			"\tvec2 cell_id = floor(scaled_uv);",
			"\tvec2 cell_uv = fract(scaled_uv);",
			"\t",
			"\t// Instead of creaing one value for each tile, we create two that we can use for a line",
			"\t// to cut with.",
			"\t// Two random values for each cell",
			"\tvec2 current = skewed_uneven_cut(cell_id + seed, size, randomness);",
			"\tvec2 top = skewed_uneven_cut( cell_id + vec2(0.0, -1.0) + seed, size, randomness);",
			"\tvec2 top_right = skewed_uneven_cut( cell_id + vec2(1.0, -1.0) + seed, size, randomness);",
			"\tvec2 right = skewed_uneven_cut( cell_id + vec2(1.0, 0.0) + seed, size, randomness);",
			"\tvec2 bottom_right = skewed_uneven_cut( cell_id + vec2(1.0, 1.0) + seed, size, randomness);",
			"\tvec2 bottom = skewed_uneven_cut( cell_id + vec2(0.0, 1.0) + seed, size, randomness);",
			"\tvec2 bottom_left = skewed_uneven_cut( cell_id + vec2(-1.0, 1.0) + seed, size, randomness);",
			"\tvec2 left = skewed_uneven_cut( cell_id + vec2(-1.0, 0.0) + seed, size, randomness);",
			"\tvec2 top_left = skewed_uneven_cut( cell_id + vec2(-1.0, -1.0) + seed, size, randomness);",
			"",
			"\tvec3 color = vec3(0.0);",
			"\t",
			"\t//vec2 point = vec2(-0.5);",
			"\tvec2 a, b, c, d;",
			"\tvec4 rect;",
			"\t",
			"\t\t// Horizontal",
			"\tif (mod(cell_id.x + cell_id.y, 2.0) > 0.5) {\t\t",
			"\t\t// The nine lines for horizontal cuts",
			"\t\tvec4 current_line = (cell_id.xyxy + vec4(vec2(-1.0, current.x), vec2(2.0, current.y))) / size.xyxy;",
			"\t\tvec4 top_line = (cell_id.xyxy + vec4(vec2(top.x, -2.0), vec2(top.y, 1.0))) / size.xyxy;",
			"\t\tvec4 top_right_line = (cell_id.xyxy + vec4(vec2(0.0, -1.0 + top_right.x), vec2(3.0, -1.0 + top_right.y))) / size.xyxy;",
			"\t\tvec4 right_line = (cell_id.xyxy + vec4(vec2(1.0 + right.x, -1.0), vec2(1.0 + right.y, 2.0))) / size.xyxy;",
			"\t\tvec4 bottom_right_line = (cell_id.xyxy + vec4(vec2(0.0, 1.0 + bottom_right.x), vec2(3.0, 1.0 + bottom_right.y))) / size.xyxy;",
			"\t\tvec4 bottom_line = (cell_id.xyxy + vec4(vec2(bottom.x, 0.0), vec2(bottom.y, 3.0))) / size.xyxy;",
			"\t\tvec4 bottom_left_line = (cell_id.xyxy + vec4(vec2(-2.0, 1.0 + bottom_left.x), vec2(1.0, 1.0 + bottom_left.y))) / size.xyxy;",
			"\t\tvec4 left_line = (cell_id.xyxy + vec4( vec2(-1.0 + left.x, -1.0), vec2(-1.0 + left.y, 2.0))) / size.xyxy;",
			"\t\tvec4 top_left_line = (cell_id.xyxy + vec4(vec2(-2.0, -1.0 + top_left.x), vec2(1.0, -1.0 + top_left.y))) / size.xyxy;",
			"\t\t",
			"\t\t// if above h cut",
			"\t\t",
			"\t\tif (!point_left_of_line(current_line, uv)) {",
			"\t\t\t// if left of v cut",
			"\t\t\tif (point_left_of_line(top_line, uv)) {",
			"\t\t\t\ta = get_line_intersection(top_left_line, left_line);",
			"\t\t\t\tb = get_line_intersection(top_line, top_left_line);",
			"\t\t\t\tc = get_line_intersection(current_line, top_line);",
			"\t\t\t\td = get_line_intersection(current_line, left_line);",
			"\t\t\t\tcolor = vec3(1.0, 0.0, 0.0);",
			"\t\t\t} else {",
			"\t\t\t\ta = get_line_intersection(top_right_line, top_line);",
			"\t\t\t\tb = get_line_intersection(right_line, top_right_line);",
			"\t\t\t\tc = get_line_intersection(current_line, right_line);",
			"\t\t\t\td = get_line_intersection(current_line, top_line);",
			"\t\t\t\t",
			"\t\t\t\tcolor = vec3(0.0, 1.0, 0.0);",
			"\t\t\t}",
			"\t\t} else {",
			"\t\t\t// if right of v cut",
			"\t\t\tif (!point_left_of_line(bottom_line, uv)) {",
			"\t\t\t\ta = get_line_intersection(current_line, bottom_line);",
			"\t\t\t\tb = get_line_intersection(current_line, right_line);",
			"\t\t\t\tc = get_line_intersection(bottom_right_line, right_line);",
			"\t\t\t\td = get_line_intersection(bottom_right_line, bottom_line);",
			"\t\t\t\t",
			"\t\t\t\tcolor = vec3(0.0, 0.0, 1.0);",
			"\t\t\t} else {",
			"\t\t\t\ta = get_line_intersection(left_line, current_line);",
			"\t\t\t\tb = get_line_intersection(bottom_line, current_line);",
			"\t\t\t\tc = get_line_intersection(bottom_line, bottom_left_line);",
			"\t\t\t\td = get_line_intersection(left_line, bottom_left_line);",
			"\t\t\t\t",
			"\t\t\t\tcolor = vec3(1.0, 1.0, 0.0);",
			"\t\t\t}",
			"\t\t}",
			"\t\tbrick_uv.xy = (invBilinear(uv, a, b, c, d));",
			"\t\trect = generate_rect(a, b, c, d);",
			"\t// Vertical",
			"\t} else { ",
			"\t\t// The nine lines for horizontal cuts",
			"\t\tvec4 current_line = (cell_id.xyxy + vec4(vec2(current.x, -1.0), vec2(current.y, 2.0))) / size.xyxy;",
			"\t\tvec4 top_line = (cell_id.xyxy + vec4(vec2(-1.0, -1.0 + top.x), vec2(2.0, -1.0 + top.y))) / size.xyxy;",
			"\t\tvec4 top_right_line = (cell_id.xyxy + vec4(vec2(1.0 + top_right.x, -2.0), vec2(1.0 + top_right.y, 1.0))) / size.xyxy;",
			"\t\tvec4 right_line = (cell_id.xyxy + vec4(vec2(0.0, right.x), vec2(3.0, right.y))) / size.xyxy;",
			"\t\tvec4 bottom_right_line = (cell_id.xyxy + vec4(vec2(1.0 + bottom_right.x, 0.0), vec2(1.0 + bottom_right.y, 3.0))) / size.xyxy;",
			"\t\tvec4 bottom_line = (cell_id.xyxy + vec4(vec2(-1.0, 1.0 + bottom.x), vec2(2.0, 1.0 + bottom.y))) / size.xyxy;",
			"\t\tvec4 bottom_left_line = (cell_id.xyxy + vec4(vec2(-1.0 + bottom_left.x, 0.0), vec2(-1.0 + bottom_left.y, 3.0))) / size.xyxy;",
			"\t\tvec4 left_line = (cell_id.xyxy + vec4( vec2(-2.0, left.x), vec2(1.0, left.y))) / size.xyxy;",
			"\t\tvec4 top_left_line = (cell_id.xyxy + vec4(vec2(-1.0 + top_left.x, -2.0), vec2(-1.0 + top_left.y, 1.0))) / size.xyxy;",
			"\t\t",
			"\t\t// if left of v cut",
			"\t\tif (point_left_of_line(current_line, uv)) {",
			"\t\t\t// if above h cut",
			"\t\t\tif (!point_left_of_line(left_line, uv)) {",
			"\t\t\t\ta = get_line_intersection(top_left_line, top_line);",
			"\t\t\t\tb = get_line_intersection(current_line, top_line);",
			"\t\t\t\tc = get_line_intersection(current_line, left_line);",
			"\t\t\t\td = get_line_intersection(top_left_line, left_line);",
			"\t\t\t\t",
			"\t\t\t\tcolor = vec3(1.0, 0.0, 1.0);",
			"\t\t\t} else {",
			"\t\t\t\ta = get_line_intersection(bottom_left_line, left_line);",
			"\t\t\t\tb = get_line_intersection(current_line, left_line);",
			"\t\t\t\tc = get_line_intersection(current_line, bottom_line);",
			"\t\t\t\td = get_line_intersection(bottom_left_line, bottom_line);",
			"\t\t\t\t",
			"\t\t\t\tcolor = vec3(1.0, 0.5, 0.0);",
			"\t\t\t}",
			"\t\t} else {",
			"\t\t\t// if above h cut",
			"\t\t\tif (!point_left_of_line(right_line, uv)) {",
			"\t\t\t\ta = get_line_intersection(current_line, top_line);",
			"\t\t\t\tb = get_line_intersection(top_right_line, top_line);",
			"\t\t\t\tc = get_line_intersection(top_right_line, right_line);",
			"\t\t\t\td = get_line_intersection(current_line, right_line);",
			"\t\t\t\t",
			"\t\t\t\tcolor = vec3(0.0, 1.0, 1.0);",
			"\t\t\t} else {",
			"\t\t\t\ta = get_line_intersection(current_line, right_line);",
			"\t\t\t\tb = get_line_intersection(bottom_right_line, right_line);",
			"\t\t\t\tc = get_line_intersection(bottom_right_line, bottom_line);",
			"\t\t\t\td = get_line_intersection(current_line, bottom_line);",
			"\t\t\t\t",
			"\t\t\t\tcolor = vec3(0.5, 1.0, 0.0);",
			"\t\t\t}",
			"\t\t}",
			"\t\tbrick_uv.xy = (invBilinear(uv, a, b, c, d));",
			"\t\trect = generate_rect(a, b, c, d);",
			"\t}",
			"\t",
			"\tbrick_fill = vec4(fract(rect.xy), rect.zw - rect.xy);",
			"",
			"\tbrick_fill *= 4096.0;",
			"\tbrick_fill = round(brick_fill);",
			"\tbrick_fill /= 4096.0;",
			"\t",
			"\tbrick_uv.z = rand(brick_fill.xy);",
			"\t",
			"\tcorner_uv.xy = brick_fill.zw * 2.0 / corner * (1.0 - (2.0 * abs(brick_uv.xy - 0.5)));",
			"\tcorner_uv.x = brick_uv.x < 0.5 ? corner_uv.x : 1.0 - corner_uv.x;",
			"\tcorner_uv.y = brick_uv.y < 0.5 ? corner_uv.y : 1.0 - corner_uv.y;",
			"\tcorner_uv.z = rand( floor(brick_uv.xy * 2.0) + brick_fill.xy );",
			"\t// Calculate corner bb",
			"\tfloat half_corner_size = 1.0 / max(size.x, size.y) * corner * 0.5;",
			"\tvec2 top_centers = brick_uv.x < 0.5 ? a + (normalize(d - a) + normalize(b - a)) * half_corner_size : b + (normalize(c - b) + normalize(a - b)) * half_corner_size; ",
			"\tvec2 bottom_centers = brick_uv.x < 0.5 ? d + (normalize(a - d) + normalize(c - d)) * half_corner_size : c + (normalize(b - c) + normalize(d - c)) * half_corner_size; ",
			"\tcorner_fill.xy = brick_uv.y < 0.5 ? top_centers : bottom_centers;",
			"\tcorner_fill.xy -= half_corner_size;",
			"\tcorner_fill.zw = vec2(half_corner_size * 2.0);",
			"\tcorner_fill = fract(round(corner_fill*grid_size)/grid_size);",
			"",
			"\t// Render the bricks",
			"\tbevel /= max(size.x, size.y) / 2.0;",
			"\tmortar /= max(size.x, size.y) / 2.0;",
			"\tfloat brick;",
			"\tvec2 dist = (min(brick_uv.xy, 1.0 - brick_uv.xy) * -2.0);",
			"\tdist *=  brick_fill.zw;",
			"\tdist += vec2(round_radius+mortar);",
			"\tbrick = length(max(dist, vec2(0))) + min(max(dist.x, dist.y), 0.0) - round_radius;",
			"\tbrick = clamp(-brick/bevel, 0.0, 1.0);",
			"\t",
			"\treturn brick;",
			"}"
		],
		"includes": [
			"skewed_bricks"
		],
		"inputs": [
			{
				"default": "1.0",
				"label": "4:",
				"longdesc": "A map that affects the Mortar parameter",
				"name": "mortar_map",
				"shortdesc": "Mortar Map",
				"type": "f"
			},
			{
				"default": "1.0",
				"label": "",
				"longdesc": "A map that affects the Bevel parameter",
				"name": "bevel_map",
				"shortdesc": "Bevel Map",
				"type": "f"
			},
			{
				"default": "1.0",
				"label": "",
				"longdesc": "A map that affects the Round parameter",
				"name": "round_map",
				"shortdesc": "Round Map",
				"type": "f"
			}
		],
		"instance": "",
		"longdesc": "Generates an uneven bricks pattern with randomly skewed cuts",
		"name": "Skewed Uneven Bricks",
		"outputs": [
			{
				"f": "$(name_uv)_bricks",
				"longdesc": "A grayscale image that shows the bricks pattern",
				"shortdesc": "Bricks Pattern",
				"type": "f"
			},
			{
				"longdesc": "A UV layout that exactly matches the skewed brick, use this output with the Custom UV node.",
				"rgb": "$(name_uv)_brick_uv",
				"shortdesc": "Skewed Bricks UV",
				"type": "rgb"
			},
			{
				"longdesc": "A UV layout that exactly matches the skewed brick's corners, use this output with the Custom UV node. For a perfectly square corner uv, use the Corner Fill output and Fill to UV node.",
				"rgb": "$(name_uv)_corner_uv",
				"shortdesc": "Skewed Corner UV",
				"type": "rgb"
			},
			{
				"fill": "$(name_uv)_brick_fill",
				"longdesc": "An output that should be plugged into a Fill companion node",
				"shortdesc": "Brick Fill",
				"type": "fill"
			},
			{
				"fill": "$(name_uv)_corner_fill",
				"longdesc": "An output that should be plugged into a Fill companion node",
				"shortdesc": "Corner Fill",
				"type": "fill"
			}
		],
		"parameters": [
			{
				"control": "None",
				"default": 6,
				"label": "Rows",
				"longdesc": "The number of rows of a pattern",
				"max": 64,
				"min": 0,
				"name": "rows",
				"shortdesc": "Rows",
				"step": 2,
				"type": "float"
			},
			{
				"control": "None",
				"default": 6,
				"label": "Columns",
				"longdesc": "The number of columns of a pattern",
				"max": 64,
				"min": 0,
				"name": "columns",
				"shortdesc": "Columns",
				"step": 2,
				"type": "float"
			},
			{
				"control": "None",
				"default": 1,
				"label": "Randomness",
				"longdesc": "The randomness of the pattern",
				"max": 1,
				"min": 0,
				"name": "randomness",
				"shortdesc": "Randomness",
				"step": 0.01,
				"type": "float"
			},
			{
				"control": "None",
				"default": 0.1,
				"label": "Mortar",
				"longdesc": "The width of the space between bricks",
				"max": 1,
				"min": 0,
				"name": "mortar",
				"shortdesc": "Mortar",
				"step": 0.01,
				"type": "float"
			},
			{
				"control": "None",
				"default": 0.1,
				"label": "Bevel",
				"longdesc": "The width of the edge of each brick",
				"max": 0.5,
				"min": 0,
				"name": "bevel",
				"shortdesc": "Bevel",
				"step": 0.01,
				"type": "float"
			},
			{
				"control": "None",
				"default": 0,
				"label": "Round",
				"longdesc": "The radius of the round corners of bricks",
				"max": 1,
				"min": 0,
				"name": "round",
				"shortdesc": "Round",
				"step": 0.01,
				"type": "float"
			},
			{
				"control": "None",
				"default": 0.3,
				"label": "Corner",
				"longdesc": "The size of the corner part of each brick (only used to calculate the Corner UV and Corner Fill outputs)",
				"max": 1,
				"min": 0,
				"name": "corner",
				"shortdesc": "Corner",
				"step": 0.01,
				"type": "float"
			}
		],
		"shortdesc": "Skewed Uneven Bricks"
	},
	"type": "shader"
}