// 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/bricks [Mode] [Direction] [Width] [Height] [Depth] [Grout Size] [Grout Color] [Offset] [Noise] [Threshold] // // xs_begin // author : '@lachlanmcdonald' // arg : { name = 'Mode' var = 'm_mode' range = '0 2' value = '0' step = '1' precision = '0' } // arg : { name = 'Direction' var = 'm_direction' range = '0 3' value = '0' step = '1' precision = '0' } // arg : { name = 'Width' var = 'm_width' range = '1 256' value = '5' step = '1' precision = '0' } // arg : { name = 'Height' var = 'm_height' range = '1 256' value = '2' step = '1' precision = '0' } // arg : { name = 'Depth' var = 'm_depth' range = '1 256' value = '2' step = '1' precision = '0' } // arg : { name = 'Grout Size' var = 'm_grout_size' range = '0 256' value = '1' step = '1' precision = '0' } // arg : { name = 'Grout Color' var = 'm_grout_color' range = '0 255' value = '1' step = '1' precision = '0' } // arg : { name = 'Offset' var = 'm_offset' range = '0 256' value = '0' step = '1' precision = '0' } // arg : { name = 'Noise' var = 'm_noise' range = '0 100' value = '0' step = '1' precision = '0' } // arg : { name = 'Threshold' var = 'm_threshold' range = '0 100' value = '100' step = '1' precision = '0' } // xs_end int mode = int(m_mode); int direction = int(m_direction); float width = m_width; float height = m_height; float depth = m_depth; float grout = m_grout_size; float grout_color = m_grout_color; float row_offset = m_offset; float noise = m_noise / 100.0; float threshold = m_threshold / 100.0; float hash(vec2 p, float seed) { p += 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(vec3 co, float seed) { float a = hash(co.xy, seed); return hash(vec2(a, co.z), seed); } float pal(float p) { float f = floor(mix(0.0, float(i_num_color_sels), p)); return color_sel(f); } vec3 mod3(vec3 a, vec3 b) { return vec3(mod(a.x, b.x), mod(a.y, b.y), mod(a.z, b.z)); } vec3 brick(vec3 p, vec3 dim, float offset) { vec3 bk = floor(p / dim); bk.x = floor((p.x + bk.z * (offset * (bk.y + 1.0))) / dim.x); return bk; } float map(vec3 v) { vec3 dim = vec3(width, depth, height) + grout; float d; if (direction == 0) { v = v.xyz; d = dim.x; } else if (direction == 1) { v = v.yzx; d = dim.x; } else if (direction == 2) { v = v.xzy; d = dim.y; } else if (direction == 3) { v = v.yxz; d = dim.x; } float offset = (row_offset == 0.0) ? floor(d / 2.0) : row_offset; vec3 bk = brick(v, dim, offset); vec3 iv = vec3(v.x + bk.z * (offset * (bk.y + 1.0)), v.yz); vec3 ic = mod3(iv, dim); float bk_randomness = hash(bk, bk.x * bk.y); if (bk_randomness < threshold) { if (any(greaterThanEqual(ic, floor(dim - grout)))) { return grout_color; } else { float bk_color; if (mode == 0) { float r = hash(bk, 0.0); bk_color = r; } else if (mode == 1) { float m = ceil(i_volume_size.z / dim.z); if (direction == 0) { bk_color = (bk.z / m); } else if (direction == 1) { bk_color = (bk.y / m); } else if (direction == 2) { bk_color = (bk.y / m); } else if (direction == 3) { bk_color = (bk.z / m); } } else if (mode == 2) { float m = ceil(i_volume_size.z / dim.z); if (direction == 0) { bk_color = (1.0 - bk.z / m); } else if (direction == 1) { bk_color = (1.0 - bk.y / m); } else if (direction == 2) { bk_color = (1.0 - bk.y / m); } else if (direction == 3) { bk_color = (1.0 - bk.z / m); } } if (hash(v, 0.0) < noise) { return pal(hash(v, 64.0)); } else { return pal(bk_color); } } } else { return 0.0; } }