// 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) 2020 ValgoBoi // MIT License (MIT) // https://github.com/ValgoBoi/clover-noise/blob/master/LICENSE // // xs brush/tiles_uneven [Mode] [Min] [Max] [Line Color] [Line Width] [Noise] [Seed] // // xs_begin // author : '@lmcdx.bsky.social' // arg : { name = 'Mode' var = 'm_mode' range = '0 5' value = '0' step = '1' precision = '0' } // arg : { name = 'Min' var = 'm_min' range = '1 256' value = '4' step = '1' precision = '0' } // arg : { name = 'Max' var = 'm_max' range = '1 256' value = '8' step = '1' precision = '0' } // arg : { name = 'Line Color' var = 'm_line_color' range = '0 255' value = '16' step = '1' precision = '0' } // arg : { name = 'Line Width' var = 'm_line_width' range = '0 256' value = '1' step = '1' precision = '0' } // arg : { name = 'Noise' var = 'm_noise' 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); float thickness = m_line_width; float size_min = min(m_min, m_max) + thickness; float size_max = max(m_min, m_max) + thickness; float line_color = m_line_color; float noise = m_noise / 100.0; struct Series { float index; float size; float local; }; float hash(vec2 p, float seed) { p += seed + global_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); } Series findSeries(int limit, vec2 seed_multiplier) { float cell_index = 0.0; float cell_size = 0.0; int last_index = 0; for (int i = 0; i <= limit;) { vec2 seed = vec2(float(i) * size_max) * seed_multiplier; last_index = i; cell_index += 1.0; cell_size = floor(mix(size_min, size_max + 1.0, hash(seed))); i += int(cell_size); } float local_pos = (cell_index == 0.0) ? float(limit) : float(limit - last_index); Series j = Series(cell_index, cell_size, local_pos); return j; } float pal(float p) { float f = floor(mix(0.0, float(i_num_color_sels), p)); return color_sel(f); } float noisePal(float p, vec3 v) { if (noise > 0.0) { float d = hash(v.xy, global_seed * 2.0); return d <= noise ? pal(d) : pal(p); } else { return pal(p); } } float map(vec3 v) { Series x = findSeries(int(v.x), vec2(64.0, 0.0)); float offset = ceil(mix(size_min, size_max, hash(vec2(x.index, 0.0)))); float k = mod(x.index, 2.0) == 0.0 ? v.y : v.y + offset; Series y = findSeries(int(k), vec2( 0.0, 64.0)); vec2 index = vec2(x.index, y.index); vec2 local = vec2(x.local, y.local); vec2 size = vec2(x.size, y.size); if (all(lessThan(local.xy, size.xy - vec2(thickness)))) { if (mode == 0) { float f = hash(index.xy); return noisePal(f, v); } else if (mode == 1) { float f = smoothstep(size_min * size_min, size_max * size_max, size.x * size.y); return noisePal(f, v); } else if (mode == 2) { float f = mod(index.x, float(i_num_color_sels)) / float(i_num_color_sels); return noisePal(f, v); } else if (mode == 3) { float f = mod(index.y, float(i_num_color_sels)) / float(i_num_color_sels); return noisePal(f, v); } else if (mode == 4) { float f = hash(index.xy); return f > 0.5 ? noisePal(0.0, v) : noisePal(1.0, v); } else if (mode == 5) { return mod(index.y, 2.0) == 0.0 ? noisePal(0.0, v) : noisePal(1.0, v); } } else { return line_color; } }