master
parent
4c6a840b39
commit
24b6616c09
@ -0,0 +1,44 @@
|
|||||||
|
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://cn575sh80pqxk"]
|
||||||
|
|
||||||
|
[ext_resource type="Shader" uid="uid://xk1b514pohnb" path="res://render/shader/level_water.gdshader" id="1_bicx1"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://c4byf37he3mjt" path="res://render/texture/particle/noise/noise1.png" id="2_a8f7n"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
render_priority = 0
|
||||||
|
shader = ExtResource("1_bicx1")
|
||||||
|
shader_parameter/absorption_color = Color(1, 0.35, 0, 1)
|
||||||
|
shader_parameter/fresnel_radius = 2.0
|
||||||
|
shader_parameter/fresnel_color = Color(0.399448, 0.529015, 0.668499, 1)
|
||||||
|
shader_parameter/roughness = 0.15
|
||||||
|
shader_parameter/specular = 0.1
|
||||||
|
shader_parameter/depth_distance = 25.0
|
||||||
|
shader_parameter/beers_law = 2.0
|
||||||
|
shader_parameter/displacement_strength = 0.0
|
||||||
|
shader_parameter/displacement_scroll_speed = 0.1
|
||||||
|
shader_parameter/displacement_scroll_offset = Vector2(-0.2, 0.3)
|
||||||
|
shader_parameter/displacement_scale_offset = 0.5
|
||||||
|
shader_parameter/displacement_scale = Vector2(0.04, 0.04)
|
||||||
|
shader_parameter/edge_thickness = 0.08
|
||||||
|
shader_parameter/edge_speed = 0.35
|
||||||
|
shader_parameter/edge_noise_scale = Vector2(0.4, 0.4)
|
||||||
|
shader_parameter/influence_size = 1.0
|
||||||
|
shader_parameter/player_wave_frequenzy = 10.0
|
||||||
|
shader_parameter/player_wave_speed = 5.0
|
||||||
|
shader_parameter/caustic_size = 2.0
|
||||||
|
shader_parameter/caustic_range = 40.0
|
||||||
|
shader_parameter/caustic_strength = 0.08
|
||||||
|
shader_parameter/ssr_mix_strength = 0.2
|
||||||
|
shader_parameter/ssr_travel = 100.0
|
||||||
|
shader_parameter/ssr_resolution_near = 0.1
|
||||||
|
shader_parameter/ssr_resolution_far = 2.0
|
||||||
|
shader_parameter/ssr_tolerance = 1.0
|
||||||
|
shader_parameter/refraction_strength = 0.01
|
||||||
|
shader_parameter/normal_map_strength = 0.5
|
||||||
|
shader_parameter/scroll_speed = 0.03
|
||||||
|
shader_parameter/scroll_offset = Vector2(0.1, 0.1)
|
||||||
|
shader_parameter/scale_offset = 0.5
|
||||||
|
shader_parameter/normal_map_scale = Vector2(0.7, 0.7)
|
||||||
|
shader_parameter/normal_map = ExtResource("2_a8f7n")
|
||||||
|
shader_parameter/wind_intensity = 2.0
|
||||||
|
shader_parameter/wind_direction = Vector3(1, 0, 0)
|
||||||
|
shader_parameter/player_position = null
|
||||||
@ -0,0 +1,342 @@
|
|||||||
|
shader_type spatial;
|
||||||
|
render_mode shadows_disabled;
|
||||||
|
|
||||||
|
#define CAUSTICS
|
||||||
|
#define FRESNEL
|
||||||
|
#define PLAYER_WAVES
|
||||||
|
#define DISPLACEMENT
|
||||||
|
#define SSR
|
||||||
|
|
||||||
|
group_uniforms color;
|
||||||
|
uniform vec3 absorption_color : source_color = vec3(1.0, 0.35, 0.0);
|
||||||
|
#ifdef FRESNEL
|
||||||
|
uniform float fresnel_radius : hint_range(0.0, 6.0, 0.01) = 2.0;
|
||||||
|
uniform vec3 fresnel_color : source_color = vec3(0.0, 0.57, 0.72);
|
||||||
|
#endif
|
||||||
|
uniform float roughness : hint_range(0.0, 1.0, 0.01) = 0.15;
|
||||||
|
uniform float specular : hint_range(0.0, 1.0, 0.01) = 0.25;
|
||||||
|
// Depth adjustment
|
||||||
|
uniform float depth_distance : hint_range(0.0, 50.0, 0.1) = 25.0;
|
||||||
|
uniform float beers_law : hint_range(0.0, 20.0, 0.1) = 4.5;
|
||||||
|
|
||||||
|
#ifdef DISPLACEMENT
|
||||||
|
group_uniforms displacement;
|
||||||
|
uniform float displacement_strength : hint_range(0.0, 5.0, 0.1) = 0.3;
|
||||||
|
uniform float displacement_scroll_speed : hint_range(0.0, 1.0, 0.001) = 0.1;
|
||||||
|
uniform vec2 displacement_scroll_offset = vec2 (-0.2, 0.3);
|
||||||
|
uniform float displacement_scale_offset = 0.5;
|
||||||
|
uniform vec2 displacement_scale = vec2(0.04);
|
||||||
|
uniform sampler2D displacement_texture : hint_default_black, repeat_enable;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
group_uniforms edge;
|
||||||
|
uniform float edge_thickness : hint_range(0.0, 1.0, 0.001) = 0.3;
|
||||||
|
uniform float edge_speed : hint_range(0.0, 1.0, 0.001) = 0.35;
|
||||||
|
uniform vec2 edge_noise_scale = vec2(0.4);
|
||||||
|
uniform sampler2D edge_noise : repeat_enable;
|
||||||
|
uniform sampler2D edge_ramp : repeat_disable;
|
||||||
|
|
||||||
|
#ifdef PLAYER_WAVES
|
||||||
|
group_uniforms player;
|
||||||
|
uniform float influence_size : hint_range(0.0, 4.0, 0.1) = 1.0;
|
||||||
|
uniform float player_wave_frequenzy : hint_range(0.0, 20.0, 0.1) = 10.0;
|
||||||
|
uniform float player_wave_speed : hint_range(0.0, 10.0, 0.1) = 5.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CAUSTICS
|
||||||
|
group_uniforms caustics;
|
||||||
|
uniform float caustic_size : hint_range(0.0, 8.0, 0.01) = 2.0;
|
||||||
|
uniform float caustic_range : hint_range(0.0, 256.0, 0.1) = 40.0;
|
||||||
|
uniform float caustic_strength : hint_range(0.0, 1.0, 0.01) = 0.08;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SSR
|
||||||
|
group_uniforms screen_space_reflections;
|
||||||
|
uniform float ssr_mix_strength : hint_range(0.0, 1.0, 0.01) = 0.65;
|
||||||
|
uniform float ssr_travel : hint_range(0.0, 300.0, 0.5) = 100.0;
|
||||||
|
uniform float ssr_resolution_near : hint_range(0.1, 10.0, 0.1) = 1.0;
|
||||||
|
uniform float ssr_resolution_far : hint_range(2.0, 20.0, 0.1) = 5.0;
|
||||||
|
uniform float ssr_tolerance : hint_range(0.0, 2.0, 0.01) = 1.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
group_uniforms normal_map;
|
||||||
|
uniform float refraction_strength : hint_range(0.0, 4.0, 0.01) = 1.25;
|
||||||
|
uniform float normal_map_strength : hint_range(0.0, 4.0, 0.01) = 1.0;
|
||||||
|
uniform float scroll_speed : hint_range(0.0, 1.0, 0.01) = 0.3;
|
||||||
|
uniform vec2 scroll_offset = vec2(0.1, -0.3);
|
||||||
|
uniform float scale_offset = 0.5;
|
||||||
|
uniform vec2 normal_map_scale = vec2(0.1);
|
||||||
|
uniform sampler2D normal_map : hint_normal, filter_linear_mipmap;
|
||||||
|
|
||||||
|
// Hidden Uniforms
|
||||||
|
uniform float wind_intensity; // Global shader parameter between 0.0 and 1.0
|
||||||
|
uniform vec3 wind_direction;
|
||||||
|
#ifdef PLAYER_WAVES
|
||||||
|
uniform vec3 player_position;
|
||||||
|
#endif
|
||||||
|
uniform sampler2D screen_texture: hint_screen_texture, filter_linear_mipmap, repeat_disable;
|
||||||
|
uniform sampler2D depth_texture: hint_depth_texture, filter_linear_mipmap, repeat_disable;
|
||||||
|
|
||||||
|
varying vec3 global_position;
|
||||||
|
|
||||||
|
#ifdef CAUSTICS
|
||||||
|
// Permutation polynomial hash credit Stefan Gustavson
|
||||||
|
vec4 permute(vec4 t) {
|
||||||
|
return t * (t * 34.0 + 133.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gradient set is a normalized expanded rhombic dodecahedron
|
||||||
|
vec3 grad(float hash) {
|
||||||
|
|
||||||
|
// Random vertex of a cube, +/- 1 each
|
||||||
|
vec3 cube = mod(floor(hash / vec3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0;
|
||||||
|
|
||||||
|
// Random edge of the three edges connected to that vertex
|
||||||
|
// Also a cuboctahedral vertex
|
||||||
|
// And corresponds to the face of its dual, the rhombic dodecahedron
|
||||||
|
vec3 cuboct = cube;
|
||||||
|
cuboct[int(hash / 16.0)] = 0.0;
|
||||||
|
|
||||||
|
// In a funky way, pick one of the four points on the rhombic face
|
||||||
|
float type = mod(floor(hash / 8.0), 2.0);
|
||||||
|
vec3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct));
|
||||||
|
|
||||||
|
// Expand it so that the new edges are the same length
|
||||||
|
// as the existing ones
|
||||||
|
vec3 grad = fma(cuboct, vec3(1.22474487139), rhomb);
|
||||||
|
|
||||||
|
// To make all gradients the same length, we only need to shorten the
|
||||||
|
// second type of vector. We also put in the whole noise scale constant.
|
||||||
|
// The compiler should reduce it into the existing floats. I think.
|
||||||
|
grad *= fma(-0.042942436724648037, type, 1.0) * 3.5946317686139184;
|
||||||
|
|
||||||
|
return grad;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BCC lattice split up into 2 cube lattices
|
||||||
|
vec4 os2NoiseWithDerivativesPart(vec3 X) {
|
||||||
|
vec3 b = floor(X);
|
||||||
|
vec4 i4 = vec4(X - b, 2.5);
|
||||||
|
|
||||||
|
// Pick between each pair of oppposite corners in the cube.
|
||||||
|
vec3 v1 = b + floor(dot(i4, vec4(.25)));
|
||||||
|
vec3 v2 = b + vec3(1, 0, 0) + vec3(-1, 1, 1) * floor(dot(i4, vec4(-.25, .25, .25, .35)));
|
||||||
|
vec3 v3 = b + vec3(0, 1, 0) + vec3(1, -1, 1) * floor(dot(i4, vec4(.25, -.25, .25, .35)));
|
||||||
|
vec3 v4 = b + vec3(0, 0, 1) + vec3(1, 1, -1) * floor(dot(i4, vec4(.25, .25, -.25, .35)));
|
||||||
|
|
||||||
|
// Gradient hashes for the four vertices in this half-lattice.
|
||||||
|
vec4 hashes = permute(mod(vec4(v1.x, v2.x, v3.x, v4.x), 289.0));
|
||||||
|
hashes = permute(mod(hashes + vec4(v1.y, v2.y, v3.y, v4.y), 289.0));
|
||||||
|
hashes = mod(permute(mod(hashes + vec4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0);
|
||||||
|
|
||||||
|
// Gradient extrapolations & kernel function
|
||||||
|
vec3 d1 = X - v1; vec3 d2 = X - v2; vec3 d3 = X - v3; vec3 d4 = X - v4;
|
||||||
|
vec4 a = max(0.75 - vec4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0);
|
||||||
|
vec4 aa = a * a; vec4 aaaa = aa * aa;
|
||||||
|
vec3 g1 = grad(hashes.x); vec3 g2 = grad(hashes.y);
|
||||||
|
vec3 g3 = grad(hashes.z); vec3 g4 = grad(hashes.w);
|
||||||
|
vec4 extrapolations = vec4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4));
|
||||||
|
|
||||||
|
// Derivatives of the noise
|
||||||
|
vec4 derivative = -8.0 * mat4(vec4(d1,0.), vec4(d2,0.), vec4(d3,0.), vec4(d4,0.)) * (aa * a * extrapolations)
|
||||||
|
+ mat4(vec4(g1, 0.), vec4(g2, 0.), vec4(g3, 0.), vec4(g4, 0.)) * aaaa;
|
||||||
|
|
||||||
|
// Return it all as a vec4
|
||||||
|
return vec4(derivative.xyz, dot(aaaa, extrapolations));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotates domain, but preserve shape. Hides grid better in cardinal slices.
|
||||||
|
// Good for texturing 3D objects with lots of flat parts along cardinal planes.
|
||||||
|
vec4 os2NoiseWithDerivatives_Fallback(vec3 X) {
|
||||||
|
X = dot(X, vec3(2.0/3.0)) - X;
|
||||||
|
|
||||||
|
vec4 result = os2NoiseWithDerivativesPart(X) + os2NoiseWithDerivativesPart(X + 144.5);
|
||||||
|
|
||||||
|
return vec4(dot(result.xyz, vec3(2.0/3.0)) - result.xyz, result.w);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FRESNEL
|
||||||
|
float fresnel(vec3 normal, vec3 view) {
|
||||||
|
return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0 )), fresnel_radius);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
vec2 refract_uv(inout vec2 uv, vec3 normal, float depth){
|
||||||
|
float strength1 = refraction_strength * depth;
|
||||||
|
uv += fma(strength1, length(normal), strength1 * -1.2);
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SSR
|
||||||
|
vec2 get_uv_from_view_position(vec3 position_view_space, mat4 proj_m)
|
||||||
|
{
|
||||||
|
vec4 position_clip_space = proj_m * vec4(position_view_space.xyz, 1.0);
|
||||||
|
vec2 position_ndc = position_clip_space.xy / position_clip_space.w;
|
||||||
|
return position_ndc.xy * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 get_view_position_from_uv(vec2 uv, float depth, mat4 inv_proj_m)
|
||||||
|
{
|
||||||
|
vec4 position_ndc = vec4((uv * 2.0) - 1.0, depth, 1.0);
|
||||||
|
vec4 view_position = inv_proj_m * position_ndc;
|
||||||
|
return view_position.xyz /= view_position.w;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool in_bounds(vec2 uv) {
|
||||||
|
vec2 fruv = abs(floor(uv));
|
||||||
|
return fruv.x + fruv.y < 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void vertex() {
|
||||||
|
global_position = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||||
|
|
||||||
|
#ifdef DISPLACEMENT
|
||||||
|
float time = TIME * displacement_scroll_speed * fma(wind_intensity, 0.7, 0.3);
|
||||||
|
float displace1 = texture(displacement_texture, fma(global_position.xz, displacement_scale, time * -wind_direction.xz)).r;
|
||||||
|
float displace2 = texture(displacement_texture, fma(global_position.xz, displacement_scale * displacement_scale_offset, time * (-wind_direction.xz + displacement_scroll_offset))).r;
|
||||||
|
float displacement_mixed = mix(displace1, displace2, 0.4);
|
||||||
|
float offset = fma(displacement_mixed, 2.0, -1.0) * displacement_strength;
|
||||||
|
VERTEX.y += offset;
|
||||||
|
global_position.y += offset;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
vec3 opposing_color = vec3(1.0) - absorption_color.rgb;
|
||||||
|
vec3 normalized_wind_direction = normalize(wind_direction);
|
||||||
|
float wind_intens_factor = fma(wind_intensity, 0.7, 0.3);
|
||||||
|
#ifdef FRESNEL
|
||||||
|
float fresnel_value = fresnel(NORMAL, VIEW);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float time_factor = TIME * scroll_speed * wind_intens_factor;
|
||||||
|
vec3 n1 = textureLod(normal_map, fma(global_position.xz, normal_map_scale, time_factor * -normalized_wind_direction.xz), 2.0).xyz;
|
||||||
|
vec3 n2 = textureLod(normal_map, fma(global_position.xz, normal_map_scale * scale_offset, time_factor * 0.8 * (-normalized_wind_direction.xz + scroll_offset)), 2.0).xyz;
|
||||||
|
NORMAL_MAP = mix(n1, n2, 0.5);
|
||||||
|
NORMAL_MAP_DEPTH = normal_map_strength;
|
||||||
|
|
||||||
|
float depth_tex = texture(depth_texture, SCREEN_UV).r;
|
||||||
|
|
||||||
|
vec3 ndc = vec3(fma(SCREEN_UV, vec2(2.0), vec2(-1.0)), depth_tex);
|
||||||
|
vec4 world = INV_VIEW_MATRIX * INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
|
||||||
|
world.y /= world.w;
|
||||||
|
float vertey_y = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).y;
|
||||||
|
float relative_depth = vertey_y - world.y;
|
||||||
|
|
||||||
|
|
||||||
|
// Create Edge caused by other Objects
|
||||||
|
float edge_blend = clamp(relative_depth / -edge_thickness + 1.0, 0.0, 1.0);
|
||||||
|
vec2 edge_noise_uv = global_position.xz * edge_noise_scale * fma(normalized_wind_direction.xz, vec2(0.5), vec2(0.5));
|
||||||
|
edge_noise_uv = fma(-normalized_wind_direction.xz * TIME * edge_speed, vec2(wind_intens_factor), edge_noise_uv);
|
||||||
|
float edge_noise_sample = texture(edge_noise, edge_noise_uv).r;
|
||||||
|
float edge_mask = normalize( texture(edge_ramp, vec2(edge_noise_sample * fma(edge_blend, -1., 1.))).r);
|
||||||
|
|
||||||
|
// Create Ripples caused by player
|
||||||
|
float player_effect_mask = 0.0;
|
||||||
|
#ifdef PLAYER_WAVES
|
||||||
|
vec3 player_relative = vec3(global_position - player_position);
|
||||||
|
float player_height = smoothstep(1.0, 0.0, abs(player_relative.y));
|
||||||
|
float player_position_factor = smoothstep(influence_size, 0.0, length(player_relative.xz));
|
||||||
|
float player_waves = pow( fma( sin(fma(player_position_factor, player_wave_frequenzy, TIME * player_wave_speed)), 0.5, 0.5), 6.0);
|
||||||
|
float wave_distort = texture( edge_ramp, vec2( player_waves * (edge_noise_sample + 0.2) * player_position_factor * player_height)).x;
|
||||||
|
player_effect_mask = clamp(normalize( fma(wave_distort, -1.0, 0.4)), 0.0, 1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// combine Edge Mask with Player Ripples
|
||||||
|
float ripple_mask = clamp( fma( edge_mask, edge_blend, player_effect_mask), 0.0, 1.0);
|
||||||
|
|
||||||
|
// Calculate Fragment Depth
|
||||||
|
vec4 clip_pos = PROJECTION_MATRIX * vec4(VERTEX, 1.0);
|
||||||
|
clip_pos.xyz /= clip_pos.w;
|
||||||
|
DEPTH = clip_pos.z;
|
||||||
|
// Refract UV
|
||||||
|
vec2 refracted_uv = SCREEN_UV;
|
||||||
|
refract_uv(refracted_uv, NORMAL_MAP, sqrt(DEPTH) * relative_depth);
|
||||||
|
|
||||||
|
vec3 screen;
|
||||||
|
float depth_blend;
|
||||||
|
float refracted_depth_tex = texture(depth_texture, refracted_uv).x;
|
||||||
|
ndc = vec3(fma(refracted_uv, vec2(2.0), vec2(-1.0)), refracted_depth_tex);
|
||||||
|
world = INV_VIEW_MATRIX * INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
|
||||||
|
world.xyz /= world.w;
|
||||||
|
float depth_test = vertey_y - world.y;
|
||||||
|
|
||||||
|
// Caustic Effects
|
||||||
|
#ifdef CAUSTICS
|
||||||
|
float range_mod = clamp((VERTEX.z + caustic_range) * 0.05, 0.0, 1.0);
|
||||||
|
float caustic_value = 0.0;
|
||||||
|
// Protect yourself from calculating Noise at runtime with this handy if statement!
|
||||||
|
if (range_mod > 0.0) {
|
||||||
|
vec3 X = vec3(world.xz * caustic_size, mod(TIME, 578.0) * 0.8660254037844386);
|
||||||
|
vec4 noiseResult = os2NoiseWithDerivatives_Fallback(X);
|
||||||
|
noiseResult = os2NoiseWithDerivatives_Fallback(X - noiseResult.xyz / 16.0);
|
||||||
|
caustic_value = fma(noiseResult.w, 0.5, 0.5) * range_mod * range_mod;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sometimes the Water Refraction would cause the sampling of a screen position that is either
|
||||||
|
outside the screen bounds or where another object is infront of the water.
|
||||||
|
Switching back to the unrefracted SCREEN_UV fixes that.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (depth_test > -0.0001 && in_bounds(refracted_uv)) {
|
||||||
|
screen = texture(screen_texture, refracted_uv).rgb * 0.9;
|
||||||
|
depth_blend = clamp(depth_test / depth_distance, 0.0, 1.0);
|
||||||
|
depth_blend = fma(exp(-depth_blend * beers_law), -1.0, 1.0);
|
||||||
|
} else {
|
||||||
|
screen = texture(screen_texture, SCREEN_UV).rgb * 0.9;
|
||||||
|
depth_blend = clamp(relative_depth / depth_distance, 0.0, 1.0);
|
||||||
|
depth_blend = fma(exp(-depth_blend * beers_law), -1.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SSR
|
||||||
|
vec3 view_normal_map = mat3(VIEW_MATRIX) * (vec3(NORMAL_MAP.x, 0.0, NORMAL_MAP.y) * 2.0 - 1.0);
|
||||||
|
vec3 combined_normal = normalize(view_normal_map * (NORMAL_MAP_DEPTH * 0.15) + NORMAL);
|
||||||
|
vec3 reflacted_path = reflect(-VIEW, combined_normal);
|
||||||
|
|
||||||
|
vec2 current_screen_pos = vec2(0.0);
|
||||||
|
vec3 current_view_pos = VERTEX;
|
||||||
|
vec3 sampled_color = vec3(-1.0);
|
||||||
|
float current_stepD = 0.0;
|
||||||
|
float current_depth = 0.0;
|
||||||
|
float alpha_hit = 0.0;
|
||||||
|
for(float i = 0.01; i < ssr_travel; i++) {
|
||||||
|
current_stepD = mix(ssr_resolution_near, ssr_resolution_far,float(i) / float(ssr_travel));
|
||||||
|
current_view_pos += reflacted_path * current_stepD;
|
||||||
|
current_screen_pos = get_uv_from_view_position(current_view_pos, PROJECTION_MATRIX);
|
||||||
|
if (!in_bounds(current_screen_pos)) {break;}
|
||||||
|
current_depth = get_view_position_from_uv(current_screen_pos, texture(depth_texture, current_screen_pos).x, INV_PROJECTION_MATRIX).z - current_view_pos.z;
|
||||||
|
|
||||||
|
if (current_depth > -0.0001 && current_depth <= ssr_tolerance * current_stepD) {
|
||||||
|
sampled_color = textureLod(screen_texture, current_screen_pos, 0.5).rgb;
|
||||||
|
vec2 ruv = 1.0 - abs(current_screen_pos * 2.0 - 1.0);
|
||||||
|
ruv = pow(ruv, vec2(0.5));
|
||||||
|
alpha_hit = clamp(min(ruv.x, ruv.y), 0.0, 1.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += current_stepD;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 color = clamp(screen - absorption_color.rgb * depth_blend, vec3(0.0), vec3(1.0)); // Absorb Screen Color
|
||||||
|
color = mix(color, opposing_color, depth_blend*depth_blend); // Apply depth color
|
||||||
|
#ifdef FRESNEL
|
||||||
|
color = mix(color, fresnel_color, fresnel_value); // Apply fresnel color
|
||||||
|
#endif
|
||||||
|
#ifdef CAUSTICS
|
||||||
|
color = clamp(color + caustic_value * caustic_strength * (1.0 - depth_blend), vec3(0.0), vec3(1.0));
|
||||||
|
#endif
|
||||||
|
#ifdef SSR
|
||||||
|
color = mix(color, sampled_color, alpha_hit * (1.0 - roughness) * ssr_mix_strength);
|
||||||
|
#endif
|
||||||
|
color = mix(color, vec3(0.98), ripple_mask); // Apply Ripples
|
||||||
|
ALBEDO = color;
|
||||||
|
ROUGHNESS = roughness;
|
||||||
|
SPECULAR = specular;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
uid://xk1b514pohnb
|
||||||
Binary file not shown.
@ -0,0 +1,18 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="MagicaVoxel.With.Extensions.To.Mesh"
|
||||||
|
type="Mesh"
|
||||||
|
uid="uid://bgj83chinak1f"
|
||||||
|
path="res://.godot/imported/chara_active_sakura01.vox-770d3961aa5c6537bc1007b00a1435e2.mesh"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://resource/mesh_level/chara_active_sakura01.vox"
|
||||||
|
dest_files=["res://.godot/imported/chara_active_sakura01.vox-770d3961aa5c6537bc1007b00a1435e2.mesh"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Scale=0.02
|
||||||
|
GreedyMeshGenerator=true
|
||||||
|
SnapToGround=false
|
||||||
|
FirstKeyframeOnly=true
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="MagicaVoxel.With.Extensions.To.Mesh"
|
||||||
|
type="Mesh"
|
||||||
|
uid="uid://dq8eokia0grit"
|
||||||
|
path="res://.godot/imported/chara_sakura01.vox-b53c3a9c27bb7444411c04726f4de78f.mesh"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://resource/mesh_level/chara_sakura01.vox"
|
||||||
|
dest_files=["res://.godot/imported/chara_sakura01.vox-b53c3a9c27bb7444411c04726f4de78f.mesh"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Scale=0.02
|
||||||
|
GreedyMeshGenerator=true
|
||||||
|
SnapToGround=false
|
||||||
|
FirstKeyframeOnly=true
|
||||||
Binary file not shown.
@ -0,0 +1,18 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="MagicaVoxel.With.Extensions.To.Mesh"
|
||||||
|
type="Mesh"
|
||||||
|
uid="uid://dbbvsgx1ufqni"
|
||||||
|
path="res://.godot/imported/deco1_cave_grass01.vox-baa1b4cc83c164c138a31fdb09886cd4.mesh"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://resource/mesh_level/deco1_cave_grass01.vox"
|
||||||
|
dest_files=["res://.godot/imported/deco1_cave_grass01.vox-baa1b4cc83c164c138a31fdb09886cd4.mesh"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Scale=0.02
|
||||||
|
GreedyMeshGenerator=true
|
||||||
|
SnapToGround=false
|
||||||
|
FirstKeyframeOnly=true
|
||||||
Binary file not shown.
@ -0,0 +1,18 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="MagicaVoxel.With.Extensions.To.Mesh"
|
||||||
|
type="Mesh"
|
||||||
|
uid="uid://bowki4ce5m2nb"
|
||||||
|
path="res://.godot/imported/deco1_cave_stone.vox-c93b5ec44d65e5d6003d7e24a06a043c.mesh"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://resource/mesh_level/deco1_cave_stone.vox"
|
||||||
|
dest_files=["res://.godot/imported/deco1_cave_stone.vox-c93b5ec44d65e5d6003d7e24a06a043c.mesh"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Scale=0.02
|
||||||
|
GreedyMeshGenerator=true
|
||||||
|
SnapToGround=false
|
||||||
|
FirstKeyframeOnly=true
|
||||||
Binary file not shown.
@ -0,0 +1,18 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="MagicaVoxel.With.Extensions.To.Mesh"
|
||||||
|
type="Mesh"
|
||||||
|
uid="uid://cesjkhckhxf0p"
|
||||||
|
path="res://.godot/imported/deco2_cave_stone.vox-974874eb2cb5bae1cca1d6bcfb619829.mesh"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://resource/mesh_level/deco2_cave_stone.vox"
|
||||||
|
dest_files=["res://.godot/imported/deco2_cave_stone.vox-974874eb2cb5bae1cca1d6bcfb619829.mesh"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Scale=0.02
|
||||||
|
GreedyMeshGenerator=true
|
||||||
|
SnapToGround=false
|
||||||
|
FirstKeyframeOnly=true
|
||||||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,18 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="MagicaVoxel.With.Extensions.To.Mesh"
|
||||||
|
type="Mesh"
|
||||||
|
uid="uid://coxbee1dskpie"
|
||||||
|
path="res://.godot/imported/result.vox-28d62b837ff8e475e393cdeea7892873.mesh"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://resource/mesh_level/result.vox"
|
||||||
|
dest_files=["res://.godot/imported/result.vox-28d62b837ff8e475e393cdeea7892873.mesh"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Scale=0.02
|
||||||
|
GreedyMeshGenerator=true
|
||||||
|
SnapToGround=false
|
||||||
|
FirstKeyframeOnly=true
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,12 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://c2chjm7aqqy78"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://script/level/level_sakura.gd" id="1_phctb"]
|
||||||
|
[ext_resource type="ArrayMesh" uid="uid://bgj83chinak1f" path="res://resource/mesh_level/chara_active_sakura01.vox" id="2_fk3jp"]
|
||||||
|
|
||||||
|
[node name="LevelSakura" type="Node3D"]
|
||||||
|
script = ExtResource("1_phctb")
|
||||||
|
metadata/_custom_type_script = ExtResource("1_phctb")
|
||||||
|
|
||||||
|
[node name="CharaActiveSakura01" type="MeshInstance3D" parent="."]
|
||||||
|
mesh = ExtResource("2_fk3jp")
|
||||||
|
skeleton = NodePath("../..")
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
extends Node3D
|
||||||
|
class_name LevelSakura
|
||||||
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
uid://5tquxl7cnwr1
|
||||||
Binary file not shown.
@ -0,0 +1,188 @@
|
|||||||
|
// MIT License (MIT)
|
||||||
|
// Copyright (c) 2020 Patrick Seeber
|
||||||
|
//
|
||||||
|
// xs_begin
|
||||||
|
// author : '@rubikow'
|
||||||
|
// arg : { id = '0' name = 'Max Volume' value = '4' range = '0 100' step = '1' decimal = '0' }
|
||||||
|
// arg : { id = '1' name = 'Random Seed' value = '123' range = '0 10000' step = '1' decimal = '2' }
|
||||||
|
// arg : { id = '2' name = 'Growth Density' value = '0.3' range = '0 1' step = '0.01' decimal = '2' }
|
||||||
|
// arg : { id = '3' name = 'Additional Colors' value = '0' range = '-255 255' step = '1' decimal = '0' }
|
||||||
|
// xs_end
|
||||||
|
|
||||||
|
float thickness = float(iArgs[0]);
|
||||||
|
float seed = float(iArgs[1]);
|
||||||
|
float density = float(iArgs[2]);
|
||||||
|
float colorRange = float(iArgs[3]);
|
||||||
|
|
||||||
|
bool isGrowColor(vec3 v){
|
||||||
|
return voxel(v) >= min(i_color_index, i_color_index + colorRange) && voxel(v) <= max(i_color_index, i_color_index + colorRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
float random(vec3 v, float seed){
|
||||||
|
float n = v.x*v.y*v.z + seed;
|
||||||
|
|
||||||
|
return abs(fract(sin(1./tan(n) + seed * 1235.342)));
|
||||||
|
}
|
||||||
|
|
||||||
|
float minDistanceToWall(vec3 v, float distance){
|
||||||
|
|
||||||
|
float minDistance = distance+1.;
|
||||||
|
|
||||||
|
for(int x=-int(distance); x<=int(distance);x++){
|
||||||
|
for(int y=-int(distance); y<=int(distance);y++){
|
||||||
|
for(int z=-int(distance); z<=int(distance);z++){
|
||||||
|
if(voxel(vec3(v.x+float(x),v.y+float(y),v.z+float(z))) != 0. && !isGrowColor(vec3(v.x+float(x),v.y+float(y),v.z+float(z)))){
|
||||||
|
float d = sqrt(pow(float(x),2.) + pow(float(y),2.) + pow(float(z),2.));
|
||||||
|
if(minDistance > d){
|
||||||
|
minDistance = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getCrowColor(vec3 v){
|
||||||
|
float distance = minDistanceToWall(v, thickness);
|
||||||
|
return i_color_index + colorRange * (distance/sqrt(pow(thickness,2.)*3.));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasWallNextToIt(vec3 v, float distance){
|
||||||
|
|
||||||
|
for(int x=-int(distance); x<=int(distance);x++){
|
||||||
|
for(int y=-int(distance); y<=int(distance);y++){
|
||||||
|
for(int z=-int(distance); z<=int(distance);z++){
|
||||||
|
if(voxel(vec3(v.x+float(x),v.y+float(y),v.z+float(z))) != 0. && !isGrowColor(vec3(v.x+float(x),v.y+float(y),v.z+float(z))) ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getFlatNeighbors(vec3 v){
|
||||||
|
int neighbors = 0;
|
||||||
|
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return neighbors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getNeighbors(vec3 v){
|
||||||
|
int neighbors = 0;
|
||||||
|
|
||||||
|
if(isGrowColor(vec3(v.x,v.y,v.z+1.))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y,v.z-1.))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return neighbors;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool growsDown(vec3 v){
|
||||||
|
|
||||||
|
if(isGrowColor(vec3(v.x,v.y,v.z+1.))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y-1.,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y+1.,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool grows(vec3 v){
|
||||||
|
int n = getNeighbors(v);
|
||||||
|
float r = random(v, seed+float(n));
|
||||||
|
if(voxel(v) != 0.){
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,-1.)) && mod(v.x+v.y,13.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,1.)) && mod(v.x+v.y,27.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,-2.)) && mod(v.x+v.y,13.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,2.)) && mod(v.x+v.y,27.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hasWallNextToIt(v, 1.) && getFlatNeighbors(v) > 3){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(r < (density) - (minDistanceToWall(v,thickness)/thickness)*(density/2.) && hasWallNextToIt(v, thickness) && n > 0 && (growsDown(v) || random(v, seed+5.567) < 0.3))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float grow(vec3 v, float seed){
|
||||||
|
if( grows(v)){
|
||||||
|
return getCrowColor(v);
|
||||||
|
}else if(isGrowColor(v) && minDistanceToWall(v, thickness) > 1.){
|
||||||
|
int n = getNeighbors(v);
|
||||||
|
float r = random(v, seed+float(n));
|
||||||
|
if((r < density + float(n)/10. + (pow(minDistanceToWall(v, thickness),2.)/pow(thickness,2.)) * 0.5)){
|
||||||
|
return 0.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return voxel(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float map(vec3 v) {
|
||||||
|
return grow(v, seed);
|
||||||
|
}
|
||||||
@ -0,0 +1,188 @@
|
|||||||
|
// MIT License (MIT)
|
||||||
|
// Copyright (c) 2020 Patrick Seeber
|
||||||
|
//
|
||||||
|
// xs_begin
|
||||||
|
// author : '@rubikow'
|
||||||
|
// arg : { id = '0' name = 'Max Volume' value = '4' range = '0 100' step = '1' decimal = '0' }
|
||||||
|
// arg : { id = '1' name = 'Random Seed' value = '123' range = '0 10000' step = '1' decimal = '2' }
|
||||||
|
// arg : { id = '2' name = 'Growth Density' value = '0.3' range = '0 1' step = '0.01' decimal = '2' }
|
||||||
|
// arg : { id = '3' name = 'Additional Colors' value = '0' range = '-255 255' step = '1' decimal = '0' }
|
||||||
|
// xs_end
|
||||||
|
|
||||||
|
float thickness = float(iArgs[0]);
|
||||||
|
float seed = float(iArgs[1]);
|
||||||
|
float density = float(iArgs[2]);
|
||||||
|
float colorRange = float(iArgs[3]);
|
||||||
|
|
||||||
|
bool isGrowColor(vec3 v){
|
||||||
|
return voxel(v) >= min(i_color_index, i_color_index + colorRange) && voxel(v) <= max(i_color_index, i_color_index + colorRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
float random(vec3 v, float seed){
|
||||||
|
float n = v.x*v.y*v.z + seed;
|
||||||
|
|
||||||
|
return abs(fract(sin(1./tan(n) + seed * 1235.342)));
|
||||||
|
}
|
||||||
|
|
||||||
|
float minDistanceToWall(vec3 v, float distance){
|
||||||
|
|
||||||
|
float minDistance = distance+1.;
|
||||||
|
|
||||||
|
for(float x=-distance; x<=distance;x+=1.){
|
||||||
|
for(float y=-distance; y<=distance;y+=1.){
|
||||||
|
for(float z=-distance; z<=distance;z+=1.){
|
||||||
|
if(voxel(vec3(v.x+x,v.y+y,v.z+z)) != 0. && !isGrowColor(vec3(v.x+x,v.y+y,v.z+z))){
|
||||||
|
float d = sqrt(pow(x,2.) + pow(y,2.) + pow(z,2.));
|
||||||
|
if(minDistance > d){
|
||||||
|
minDistance = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getCrowColor(vec3 v){
|
||||||
|
float distance = minDistanceToWall(v, thickness);
|
||||||
|
return i_color_index + colorRange * (distance/sqrt(pow(thickness,2.)*3.));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasWallNextToIt(vec3 v, float distance){
|
||||||
|
|
||||||
|
for(float x=-distance; x<=distance;x+=1.){
|
||||||
|
for(float y=-distance; y<=distance;y+=1.){
|
||||||
|
for(float z=-distance; z<=distance;z+=1.){
|
||||||
|
if(voxel(vec3(v.x+x,v.y+y,v.z+z)) != 0. && !isGrowColor(vec3(v.x+x,v.y+y,v.z+z)) ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getFlatNeighbors(vec3 v){
|
||||||
|
int neighbors = 0;
|
||||||
|
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return neighbors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getNeighbors(vec3 v){
|
||||||
|
int neighbors = 0;
|
||||||
|
|
||||||
|
if(isGrowColor(vec3(v.x,v.y,v.z+1.))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y,v.z-1.))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return neighbors;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool growsDown(vec3 v){
|
||||||
|
|
||||||
|
if(isGrowColor(vec3(v.x,v.y,v.z+1.))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y-1.,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y+1.,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool grows(vec3 v){
|
||||||
|
int n = getNeighbors(v);
|
||||||
|
float r = random(v, seed+float(n));
|
||||||
|
if(voxel(v) == 0.){
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,-1.)) && mod(v.x+v.y,13.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,1.)) && mod(v.x+v.y,27.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,-2.)) && mod(v.x+v.y,13.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,2.)) && mod(v.x+v.y,27.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hasWallNextToIt(v, 1.) && getFlatNeighbors(v) > 3){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(r < (density) - (minDistanceToWall(v,thickness)/thickness)*(density/2.) && hasWallNextToIt(v, thickness) && n > 0 && (growsDown(v) || random(v, seed+5.567) < 0.3))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float grow(vec3 v, float seed){
|
||||||
|
if( grows(v)){
|
||||||
|
return getCrowColor(v);
|
||||||
|
}else if(isGrowColor(v) && minDistanceToWall(v, thickness) > 1.){
|
||||||
|
int n = getNeighbors(v);
|
||||||
|
float r = random(v, seed+float(n));
|
||||||
|
if(r < density + float(n)/100. + (pow(minDistanceToWall(v, thickness),2.)/pow(thickness,2.)) * 0.5){
|
||||||
|
return 0.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return voxel(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float map(vec3 v) {
|
||||||
|
return grow(v, seed);
|
||||||
|
}
|
||||||
@ -0,0 +1,182 @@
|
|||||||
|
// MIT License (MIT)
|
||||||
|
// Copyright (c) 2020 Patrick Seeber
|
||||||
|
//
|
||||||
|
// xs_begin
|
||||||
|
// author : '@rubikow'
|
||||||
|
// arg : { id = '0' name = 'Max Volume' value = '4' range = '0 100' step = '1' decimal = '0' }
|
||||||
|
// arg : { id = '1' name = 'Random Seed' value = '123' range = '0 10000' step = '1' decimal = '2' }
|
||||||
|
// arg : { id = '2' name = 'Growth Density' value = '0.3' range = '0 1' step = '0.01' decimal = '2' }
|
||||||
|
// arg : { id = '3' name = 'Addition Colors' value = '0' range = '0 255' step = '1' decimal = '0' }
|
||||||
|
// xs_end
|
||||||
|
|
||||||
|
float thickness = float(iArgs[0]);
|
||||||
|
float seed = float(iArgs[1]);
|
||||||
|
float density = float(iArgs[2]);
|
||||||
|
float colorRange = float(iArgs[3]);
|
||||||
|
|
||||||
|
bool isGrowColor(vec3 v){
|
||||||
|
return voxel(v) >= min(i_color_index, i_color_index + colorRange) && voxel(v) <= max(i_color_index, i_color_index + colorRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
float random(vec3 v, float seed){
|
||||||
|
float n = v.x*v.y*v.z + seed;
|
||||||
|
|
||||||
|
return abs(fract(sin(1./tan(n) + seed * 1235.342)));
|
||||||
|
}
|
||||||
|
|
||||||
|
float minDistanceToWall(vec3 v, float distance){
|
||||||
|
|
||||||
|
float minDistance = distance+1.;
|
||||||
|
|
||||||
|
for(float x=-distance; x<=distance;x+=1.){
|
||||||
|
for(float y=-distance; y<=distance;y+=1.){
|
||||||
|
for(float z=-distance; z<=distance;z+=1.){
|
||||||
|
if(voxel(vec3(v.x+x,v.y+y,v.z+z)) != 0. && !isGrowColor(vec3(v.x+x,v.y+y,v.z+z))){
|
||||||
|
float d = sqrt(pow(x,2.) + pow(y,2.) + pow(z,2.));
|
||||||
|
if(minDistance > d){
|
||||||
|
minDistance = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getCrowColor(vec3 v){
|
||||||
|
float distance = minDistanceToWall(v, thickness);
|
||||||
|
return i_color_index + colorRange * (distance/sqrt(pow(thickness,2.)*3.));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasWallNextToIt(vec3 v, float distance){
|
||||||
|
|
||||||
|
for(float x=-distance; x<=distance;x+=1.){
|
||||||
|
for(float y=-distance; y<=distance;y+=1.){
|
||||||
|
for(float z=-distance; z<=0;z+=1.){
|
||||||
|
if(voxel(vec3(v.x+x,v.y+y,v.z+z)) != 0. && !isGrowColor(vec3(v.x+x,v.y+y,v.z+z)) ){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getFlatNeighbors(vec3 v){
|
||||||
|
int neighbors = 0;
|
||||||
|
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return neighbors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getNeighbors(vec3 v){
|
||||||
|
int neighbors = 0;
|
||||||
|
|
||||||
|
if(isGrowColor(vec3(v.x,v.y,v.z+1.))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y,v.z-1.))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y-1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y+1.,v.z))){
|
||||||
|
neighbors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return neighbors;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool growsDown(vec3 v){
|
||||||
|
|
||||||
|
if(isGrowColor(vec3(v.x,v.y,v.z+1.))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x+1.,v.y,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x-1.,v.y,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y-1.,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(isGrowColor(vec3(v.x,v.y+1.,v.z))){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool grows(vec3 v){
|
||||||
|
int n = getNeighbors(v);
|
||||||
|
float r = random(v, seed+float(n));
|
||||||
|
if(voxel(v) == 0.){
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,-1.)) && mod(v.x+v.y,13.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,1.)) && mod(v.x+v.y,27.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,-2.)) && mod(v.x+v.y,13.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(hasWallNextToIt(v, 1.) && isGrowColor(v+vec3(0,0,2.)) && mod(v.x+v.y,27.) == 0.){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hasWallNextToIt(v, 1.) && getFlatNeighbors(v) > 3){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(r < (density) - (minDistanceToWall(v,thickness)/thickness)*(density/2.) && hasWallNextToIt(v, thickness) && n > 0 && (growsDown(v) || random(v, seed+5.567) < 0.3))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float grow(vec3 v, float seed){
|
||||||
|
if( grows(v)){
|
||||||
|
return getCrowColor(v);
|
||||||
|
}
|
||||||
|
return voxel(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
float map(vec3 v) {
|
||||||
|
return grow(v, seed);
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue