mirror of
https://github.com/Relintai/material-maker.git
synced 2025-01-09 05:39:38 +01:00
Added new patterns for bricks
Added a Running Bond variant, HerringBone, Basket Weave and Spanish bond patterns to the bricks generator. Shader was refactored to make it easy to add new patterns made of axis-aligned bricks.
This commit is contained in:
parent
0d0f862a99
commit
ddbd69ea25
@ -145,21 +145,99 @@ vec2 transform_norepeat(vec2 uv, vec2 translate, float rotate, vec2 scale) {
|
||||
return clamp(transform(uv, translate, rotate, scale), vec2(0.0), vec2(1.0));
|
||||
}
|
||||
|
||||
vec3 bricks(vec2 uv, vec2 count, float offset, float mortar, float bevel) {
|
||||
vec3 brick(vec2 uv, vec2 bmin, vec2 bmax, float mortar, float bevel) {
|
||||
float color = 0.5;
|
||||
vec2 c1 = (uv-bmin-vec2(mortar))/bevel;
|
||||
vec2 c2 = (bmax-uv-vec2(mortar))/bevel;
|
||||
vec2 c = min(c1, c2);
|
||||
color = clamp(min(c.x, c.y), 0.0, 1.0);
|
||||
return vec3(color, bmin);
|
||||
}
|
||||
|
||||
vec3 bricks_rb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
count *= repeat;
|
||||
mortar /= max(count.x, count.y);
|
||||
bevel /= max(count.x, count.y);
|
||||
float x = uv.x*count.x+offset*step(0.5, fract(uv.y*count.y*0.5));
|
||||
float fract_x = fract(x);
|
||||
float slope_x = 1.0/(bevel*count.x);
|
||||
float off = 0.5*mortar/bevel;
|
||||
float f1 = fract_x*slope_x-off;
|
||||
float f2 = (1.0-fract_x)*slope_x-off;
|
||||
float y = uv.y*count.y;
|
||||
float fract_y = fract(uv.y*count.y);
|
||||
float slope_y = 1.0/(bevel*count.y);
|
||||
float f3 = fract_y*slope_y-off;
|
||||
float f4 = (1.0-fract_y)*slope_y-off;
|
||||
return vec3(max(0.0, min(1.0, min(min(f1, f2), min(f3, f4)))), floor(mod(x, count.x)), floor(mod(y, count.y)));
|
||||
float x_offset = offset*step(0.5, fract(uv.y*count.y*0.5));
|
||||
vec2 bmin = floor(vec2(uv.x*count.x-x_offset, uv.y*count.y));
|
||||
bmin.x += x_offset;
|
||||
bmin /= count;
|
||||
return brick(uv, bmin, bmin+vec2(1.0)/count, mortar, bevel);
|
||||
}
|
||||
|
||||
vec3 bricks_rb2(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
count *= repeat;
|
||||
mortar /= max(2.0*count.x, count.y);
|
||||
bevel /= max(2.0*count.x, count.y);
|
||||
float x_offset = offset*step(0.5, fract(uv.y*count.y*0.5));
|
||||
count.x = count.x*(1.0+step(0.5, fract(uv.y*count.y*0.5)));
|
||||
vec2 bmin = floor(vec2(uv.x*count.x-x_offset, uv.y*count.y));
|
||||
bmin.x += x_offset;
|
||||
bmin /= count;
|
||||
return brick(uv, bmin, bmin+vec2(1.0)/count, mortar, bevel);
|
||||
}
|
||||
|
||||
vec3 bricks_hb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
float pc = count.x+count.y;
|
||||
float c = pc*repeat;
|
||||
mortar /= c;
|
||||
bevel /= c;
|
||||
vec2 corner = floor(uv*c);
|
||||
float cdiff = mod(corner.x-corner.y, pc);
|
||||
if (cdiff < count.x) {
|
||||
return brick(uv, (corner-vec2(cdiff, 0.0))/c, (corner-vec2(cdiff, 0.0)+vec2(count.x, 1.0))/c, mortar, bevel);
|
||||
} else {
|
||||
return brick(uv, (corner-vec2(0.0, pc-cdiff-1.0))/c, (corner-vec2(0.0, pc-cdiff-1.0)+vec2(1.0, count.y))/c, mortar, bevel);
|
||||
}
|
||||
}
|
||||
|
||||
vec3 bricks_bw(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
vec2 c = 2.0*count*repeat;
|
||||
float mc = max(c.x, c.y);
|
||||
mortar /= mc;
|
||||
bevel /= mc;
|
||||
vec2 corner1 = floor(uv*c);
|
||||
vec2 corner2 = count*floor(repeat*2.0*uv);
|
||||
float cdiff = mod(dot(floor(repeat*2.0*uv), vec2(1.0)), 2.0);
|
||||
vec2 corner;
|
||||
vec2 size;
|
||||
if (cdiff == 0.0) {
|
||||
corner = vec2(corner1.x, corner2.y);
|
||||
size = vec2(1.0, count.y);
|
||||
} else {
|
||||
corner = vec2(corner2.x, corner1.y);
|
||||
size = vec2(count.x, 1.0);
|
||||
}
|
||||
return brick(uv, corner/c, (corner+size)/c, mortar, bevel);
|
||||
}
|
||||
|
||||
vec3 bricks_sb(vec2 uv, vec2 count, float repeat, float offset, float mortar, float bevel) {
|
||||
vec2 c = (count+vec2(1.0))*repeat;
|
||||
float mc = max(c.x, c.y);
|
||||
mortar /= mc;
|
||||
bevel /= mc;
|
||||
vec2 corner1 = floor(uv*c);
|
||||
vec2 corner2 = (count+vec2(1.0))*floor(repeat*uv);
|
||||
vec2 rcorner = corner1 - corner2;
|
||||
vec2 corner;
|
||||
vec2 size;
|
||||
if (rcorner.x == 0.0 && rcorner.y < count.y) {
|
||||
corner = corner2;
|
||||
size = vec2(1.0, count.y);
|
||||
} else if (rcorner.y == 0.0) {
|
||||
corner = corner2+vec2(1.0, 0.0);
|
||||
size = vec2(count.x, 1.0);
|
||||
} else if (rcorner.x == count.x) {
|
||||
corner = corner2+vec2(count.x, 1.0);
|
||||
size = vec2(1.0, count.y);
|
||||
} else if (rcorner.y == count.y) {
|
||||
corner = corner2+vec2(0.0, count.y);
|
||||
size = vec2(count.x, 1.0);
|
||||
} else {
|
||||
corner = corner2+vec2(1.0);
|
||||
size = vec2(count.x-1.0, count.y-1.0);
|
||||
}
|
||||
return brick(uv, corner/c, (corner+size)/c, mortar, bevel);
|
||||
}
|
||||
|
||||
float colored_bricks(vec2 uv, vec2 count, float offset) {
|
||||
|
@ -1,27 +1,42 @@
|
||||
tool
|
||||
extends "res://addons/procedural_material/node_base.gd"
|
||||
|
||||
var pattern = 0
|
||||
var repeat
|
||||
var rows
|
||||
var columns
|
||||
var row_offset
|
||||
var mortar
|
||||
var bevel
|
||||
|
||||
const BRICK_PATTERNS = [
|
||||
{ name="Running bond", suffix="rb", has_offset=true, has_repeat=false },
|
||||
{ name="Running bond (2)", suffix="rb2", has_offset=true, has_repeat=false },
|
||||
{ name="HerringBone", suffix="hb", has_offset=false, has_repeat=true },
|
||||
{ name="Basket weave", suffix="bw", has_offset=false, has_repeat=true },
|
||||
{ name="Spanish bond", suffix="sb", has_offset=false, has_repeat=true }
|
||||
]
|
||||
|
||||
func _ready():
|
||||
set_slot(0, false, 0, Color(0.5, 0.5, 1), true, 0, Color(0.5, 0.5, 1))
|
||||
initialize_properties([ $HBoxContainer1/rows, $HBoxContainer2/columns, $HBoxContainer3/row_offset, $HBoxContainer4/mortar, $HBoxContainer5/bevel ])
|
||||
$pattern.clear()
|
||||
for p in BRICK_PATTERNS:
|
||||
$pattern.add_item(p.name)
|
||||
initialize_properties([ $pattern, $HBoxContainer1/rows, $HBoxContainer2/columns, $HBoxContainer6/repeat, $HBoxContainer3/row_offset, $HBoxContainer4/mortar, $HBoxContainer5/bevel ])
|
||||
|
||||
func _get_shader_code(uv, slot = 0):
|
||||
var rv = { defs="", code="" }
|
||||
if generated_variants.empty():
|
||||
rv.defs = "vec3 "+name+"_xyz(vec2 uv) { return bricks(uv, vec2("+str(columns)+", "+str(rows)+"), "+str(row_offset)+", "+str(mortar)+", "+str(max(0.001, bevel))+"); }\n"
|
||||
rv.defs = "vec3 %s_xyz(vec2 uv) { return bricks_%s(uv, vec2(%d, %d), %.9f, %.9f, %.9f, %.9f); }\n" % [ name, BRICK_PATTERNS[pattern].suffix, columns, rows, repeat, row_offset, mortar, max(0.001, bevel) ]
|
||||
var variant_index = generated_variants.find(uv)
|
||||
if variant_index == -1:
|
||||
variant_index = generated_variants.size()
|
||||
generated_variants.append(uv)
|
||||
rv.code = "vec3 "+name+"_"+str(variant_index)+"_xyz = "+name+"_xyz("+uv+");\n"
|
||||
rv.code = "vec3 %s_%d_xyz = %s_xyz(%s);\n" % [ name, variant_index, name, uv ]
|
||||
if slot == 0:
|
||||
rv.f = name+"_"+str(variant_index)+"_xyz.x"
|
||||
rv.f = "%s_%d_xyz.x" % [ name, variant_index ]
|
||||
else:
|
||||
rv.rgb = "rand3("+name+"_"+str(variant_index)+"_xyz.yz)"
|
||||
rv.rgb = "rand3(%s_%d_xyz.yz+vec2(%.9f))" % [ name, variant_index, get_seed() ]
|
||||
return rv
|
||||
|
||||
func _on_offset_changed():
|
||||
update_shaders()
|
||||
|
@ -5,7 +5,7 @@
|
||||
[sub_resource type="Theme" id=1]
|
||||
|
||||
|
||||
[node name="Bricks" type="GraphNode"]
|
||||
[node name="Bricks" type="GraphNode" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
@ -58,10 +58,22 @@ slot/4/left_color = Color( 1, 1, 1, 1 )
|
||||
slot/4/right_enabled = false
|
||||
slot/4/right_type = 0
|
||||
slot/4/right_color = Color( 1, 1, 1, 1 )
|
||||
slot/5/left_enabled = false
|
||||
slot/5/left_type = 0
|
||||
slot/5/left_color = Color( 1, 1, 1, 1 )
|
||||
slot/5/right_enabled = false
|
||||
slot/5/right_type = 0
|
||||
slot/5/right_color = Color( 1, 1, 1, 1 )
|
||||
slot/6/left_enabled = false
|
||||
slot/6/left_type = 0
|
||||
slot/6/left_color = Color( 1, 1, 1, 1 )
|
||||
slot/6/right_enabled = false
|
||||
slot/6/right_type = 0
|
||||
slot/6/right_color = Color( 1, 1, 1, 1 )
|
||||
script = ExtResource( 1 )
|
||||
_sections_unfolded = [ "Mouse", "Theme", "slot", "slot/0", "slot/1" ]
|
||||
|
||||
[node name="HBoxContainer1" type="HBoxContainer" parent="." index="0"]
|
||||
[node name="pattern" type="OptionButton" parent="." index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
@ -70,7 +82,100 @@ anchor_bottom = 0.0
|
||||
margin_left = 16.0
|
||||
margin_top = 24.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 48.0
|
||||
margin_bottom = 44.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
focus_mode = 2
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
toggle_mode = false
|
||||
action_mode = 0
|
||||
enabled_focus_mode = 2
|
||||
shortcut = null
|
||||
group = null
|
||||
flat = false
|
||||
align = 0
|
||||
items = [ ]
|
||||
selected = -1
|
||||
_sections_unfolded = [ "Size Flags" ]
|
||||
|
||||
[node name="HBoxContainer6" type="HBoxContainer" parent="." index="1"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 16.0
|
||||
margin_top = 44.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 68.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 1
|
||||
alignment = 0
|
||||
|
||||
[node name="Label1" type="Label" parent="HBoxContainer6" index="0"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_top = 5.0
|
||||
margin_right = 60.0
|
||||
margin_bottom = 19.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 4
|
||||
text = "Repeat:"
|
||||
percent_visible = 1.0
|
||||
lines_skipped = 0
|
||||
max_lines_visible = -1
|
||||
|
||||
[node name="repeat" type="SpinBox" parent="HBoxContainer6" index="1"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 64.0
|
||||
margin_right = 138.0
|
||||
margin_bottom = 24.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 0
|
||||
mouse_default_cursor_shape = 0
|
||||
size_flags_horizontal = 9
|
||||
size_flags_vertical = 1
|
||||
min_value = 1.0
|
||||
max_value = 8.0
|
||||
step = 1.0
|
||||
page = 0.0
|
||||
value = 1.0
|
||||
exp_edit = false
|
||||
rounded = false
|
||||
editable = true
|
||||
prefix = ""
|
||||
suffix = ""
|
||||
_sections_unfolded = [ "Caret", "Placeholder" ]
|
||||
|
||||
[node name="HBoxContainer1" type="HBoxContainer" parent="." index="2"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 16.0
|
||||
margin_top = 69.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 93.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
@ -126,16 +231,16 @@ prefix = ""
|
||||
suffix = ""
|
||||
_sections_unfolded = [ "Caret", "Placeholder" ]
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="." index="1"]
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="." index="3"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 16.0
|
||||
margin_top = 48.0
|
||||
margin_top = 94.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 72.0
|
||||
margin_bottom = 118.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
@ -191,16 +296,16 @@ prefix = ""
|
||||
suffix = ""
|
||||
_sections_unfolded = [ "Caret", "Placeholder" ]
|
||||
|
||||
[node name="HBoxContainer3" type="HBoxContainer" parent="." index="2"]
|
||||
[node name="HBoxContainer3" type="HBoxContainer" parent="." index="4"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 16.0
|
||||
margin_top = 73.0
|
||||
margin_top = 119.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 97.0
|
||||
margin_bottom = 143.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
@ -256,16 +361,16 @@ prefix = ""
|
||||
suffix = ""
|
||||
_sections_unfolded = [ "Caret", "Placeholder" ]
|
||||
|
||||
[node name="HBoxContainer4" type="HBoxContainer" parent="." index="3"]
|
||||
[node name="HBoxContainer4" type="HBoxContainer" parent="." index="5"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 16.0
|
||||
margin_top = 98.0
|
||||
margin_top = 144.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 122.0
|
||||
margin_bottom = 168.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
@ -321,16 +426,16 @@ prefix = ""
|
||||
suffix = ""
|
||||
_sections_unfolded = [ "Caret", "Placeholder" ]
|
||||
|
||||
[node name="HBoxContainer5" type="HBoxContainer" parent="." index="4"]
|
||||
[node name="HBoxContainer5" type="HBoxContainer" parent="." index="6"]
|
||||
|
||||
anchor_left = 0.0
|
||||
anchor_top = 0.0
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_left = 16.0
|
||||
margin_top = 123.0
|
||||
margin_top = 169.0
|
||||
margin_right = 154.0
|
||||
margin_bottom = 147.0
|
||||
margin_bottom = 193.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 1
|
||||
@ -386,4 +491,6 @@ prefix = ""
|
||||
suffix = ""
|
||||
_sections_unfolded = [ "Caret", "Placeholder" ]
|
||||
|
||||
[connection signal="offset_changed" from="." to="." method="_on_offset_changed"]
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user