2
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.3 KiB
Plaintext

// 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 <https://github.com/ValgoBoi/clover-noise>
// MIT License (MIT)
// https://github.com/ValgoBoi/clover-noise/blob/master/LICENSE
//
// xs brush/grass [Direction] [Mode] [Density] [Growth] [Seed]
//
// xs_begin
// author : '@lachlanmcdonald'
// arg : { name = 'Direction' var = 'm_direction' range = '0 1' value = '0' step = '1' precision = '0' }
// arg : { name = 'Mode' var = 'm_mode' range = '0 4' value = '0' step = '1' precision = '0' }
// arg : { name = 'Density' var = 'm_density' range = '1 256' value = '2' step = '1' precision = '0' }
// arg : { name = 'Growth' var = 'm_growth' range = '0 100' value = '50' step = '1' precision = '0' }
// arg : { name = 'Seed' var = 'global_seed' range = '1 100' value = '1' step = '1' precision = '0' }
// xs_end
int direction = int(m_direction);
int mode = int(m_mode);
float density = m_density;
float growth = mix(1.0, -1.0, m_growth / 100.0);
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);
}
float pal(float p) {
float f = floor(mix(0.0, float(i_num_color_sels), p));
return color_sel(f);
}
float map(vec3 v) {
if (direction == 1) {
v.z = i_volume_size.z - v.z;
}
vec2 cell = floor(vec2(v.xy) / density);
vec3 local = floor(mod(v, density));
vec2 placement = floor(vec2(hash(cell.xy), hash(cell.xy, 170.3170)) * density);
if (all(equal(local.xy, placement))) {
float height = hash(cell.yx, -170.3170);
float z = v.z / i_volume_size.z;
float p = 1.0 - sqrt(1.0 - pow(height, 2.0));
float p2 = mix(height, p, growth);
if (z < p2) {
float f;
if (mode == 0) {
f = p2;
} else if (mode == 1) {
f = hash(vec2(z, p));
} else if (mode == 2) {
f = hash(v.xy);
} else if (mode == 3) {
f = z / p2;
} else if (mode == 4) {
f = 1.0 - (z / p2);
}
return pal(f);
}
}
return 0.0;
}