// Copyright (c) 2023 Lachlan McDonald // This work is licensed under the MIT License (MIT) // https://github.com/lachlanmcdonald/magicavoxel-shaders // // This script utilises or modifies code from other projects or publications. // Please see the attributions below for more information: // // 1. Copyright (c) 2011 Stefan Gustavson // MIT License (MIT) // https://github.com/ashima/webgl-noise/blob/master/LICENSE // // 2. Copyright (c) 2020 ValgoBoi // MIT License (MIT) // https://github.com/ValgoBoi/clover-noise/blob/master/LICENSE // // xs brush/truchet [Mode] [Size] [Line Color] [Line Width] [Jitter] [Seed] // // xs_begin // author : '@lmcdx.bsky.social' // arg : { name = 'Mode' var = 'm_mode' range = '0 1' value = '0' step = '1' precision = '0' } // arg : { name = 'Size' var = 'm_size' range = '3 40' value = '8' step = '1' precision = '0' } // arg : { name = 'Line Color' var = 'm_line_color' range = '0 255' value = '10' step = '1' precision = '0' } // arg : { name = 'Line Width' var = 'm_line_width' range = '0 256' value = '1' step = '1' precision = '0' } // arg : { name = 'Jitter' var = 'm_jitter' range = '0 100' value = '0' step = '1' precision = '0' } // arg : { name = 'Seed' var = 'global_seed' range = '1 100' value = '1' step = '1' precision = '0' } // xs_end int mode = int(m_mode); vec2 dim = vec2(m_size + m_line_width); float jitter = m_jitter / 100.0; float hash(vec2 p, float seed) { p += global_seed + seed; return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); } float hash(vec2 co) { return hash(co, 0.0); } vec2 hash22(vec2 p, float seed) { float a = hash(p, seed); return vec2(a, hash(p + a, seed)); } vec2 hash22(vec2 p) { return hash22(p, 0.0); } float roundf(float f) { return f >= 0.5 ? ceil(f) : floor(f); } float pal(float f) { float k = float(i_num_color_sels) * clamp(0.0, 1.0, f); return color_sel(k); } float map(vec3 v) { vec2 cell = floor(v.xy / dim); vec2 local = mod(v.xy, dim); if (any(lessThan(local, vec2(m_line_width)))) { return m_line_color; } else { float a, b; vec2 j = hash22(cell); int rotate = int(hash(cell, 256.0) * 4.0); float dist; int comp; if (rotate == 0) { comp = 0; dist = (local.x + local.y) / (dim.x + dim.y); } else if (rotate == 1) { comp = 0; dist = ((dim.x - local.x) + local.y) / (dim.x + dim.y); } else if (rotate == 2) { comp = 0; dist = (local.x + (dim.y - local.y)) / (dim.x + dim.y); } else { comp = 1; dist = ((dim.x - local.x) + (dim.y - local.y)) / (dim.x + dim.y); } if (jitter > 0.0) { dist += mix(-1.0, 1.0, hash(v.xy)) * jitter; } if (mode == 0) { if (i_num_color_sels <= 2) { a = 0.0; b = 1.0; } else { float ka, kb; do { j = hash22(j); a = j.x; b = j.y; ka = floor(float(i_num_color_sels) * clamp(0.0, 1.0, a)); kb = floor(float(i_num_color_sels) * clamp(0.0, 1.0, b)); } while (ka == kb); } } else if (mode == 1) { a = mix(0.0, 0.5, j.x); b = mix(0.5, 1.0, j.x); } a = pal(a); b = pal(b); if (comp == 0) { return dist > 0.5 ? a : b; } else if (comp == 1) { return dist >= 0.5 ? a : b; } } }