master
chendian 9 months ago
parent 4c6a840b39
commit 24b6616c09

@ -35,6 +35,15 @@ func _enter_tree():
add_short_cut("配置-武器技能", "res://config/skill_player_weapon")
add_short_cut("资产-技能特效", "res://scene/effect/particle")
add_short_cut("资产-AI", "res://scene/ai")
add_short_cut("资产-场景活动物件", "res://scene/level_active")
add_short_cut("编辑场景-关卡", "res://scene/level/level.tscn")
add_short_cut("编辑场景-角色", "res://scene/character/character.tscn")
add_short_cut("打印meshlib-main", "res://resource/mesh_library/mesh_library_main.tres")
add_short_cut("打印meshlib-sub", "res://resource/mesh_library/mesh_library_sub.tres")
add_short_cut("打印meshlib-deco1", "res://resource/mesh_library/mesh_library_deco1.tres")
add_short_cut("打印meshlib-deco2", "res://resource/mesh_library/mesh_library_deco2.tres")
add_short_cut("打印meshlib-chara", "res://resource/mesh_library/mesh_library_chara.tres")
add_short_cut("功能-修复meshlib材质", "func_fix_mesh")
func add_short_cut(target_name: String, path: String):
@ -55,7 +64,50 @@ func skill_popup_index_pressed(index: int):
func short_cut_index_pressed(index: int):
EditorInterface.select_file(short_cut_path_list[index])
var short_cut_path: String = short_cut_path_list[index]
if short_cut_path.ends_with(".tscn"):
EditorInterface.select_file(short_cut_path)
EditorInterface.open_scene_from_path(short_cut_path)
return
elif short_cut_path.ends_with(".tres"):
#todo 目前只有meshlib
var mesh_library: MeshLibrary = ResourceLoader.load(short_cut_path)
print("[", short_cut_path, "]")
for item_id: int in mesh_library.get_item_list():
var mesh: Mesh = mesh_library.get_item_mesh(item_id)
var surface_count: int = mesh.get_surface_count()
var material_name: String = "null"
if surface_count > 0:
material_name = mesh.surface_get_material(0).resource_path
if material_name.begins_with("res://.godot/imported"):
material_name = "inner"
elif material_name.begins_with("res://render/material"):
material_name = material_name.trim_prefix("res://render/material/").trim_suffix(".tres")
else:
material_name = "null"
print("[", item_id, "]", mesh_library.get_item_name(item_id), "::", material_name)
elif short_cut_path == "func_fix_mesh":
var material: Material = ResourceLoader.load("res://render/material/level_grid_block.tres")
var dir_path: String = "res://resource/mesh_library"
var dir: DirAccess = DirAccess.open(dir_path)
for file: String in dir.get_files():
var path: String = dir_path + "/" + file
var res: Resource = load(path)
var fix_count: int = 0
if not res is MeshLibrary:
continue
var mesh_library: MeshLibrary = res as MeshLibrary
for item_id: int in mesh_library.get_item_list():
var mesh: Mesh = mesh_library.get_item_mesh(item_id)
for surface_id: int in range(mesh.get_surface_count()):
if not mesh.surface_get_material(surface_id) == material:
fix_count += 1
mesh.surface_set_material(surface_id, material)
ResourceSaver.save(mesh, mesh.get_path())
ResourceSaver.save(res, path)
print("修复meshlib材质(", fix_count, "):", path)
else:
EditorInterface.select_file(short_cut_path)
func _process(delta: float) -> void:
@ -79,7 +131,7 @@ func _process(delta: float) -> void:
EditorInterface.open_scene_from_path("res://scene/character/character.tscn")
var root: Node = EditorInterface.get_edited_scene_root()
var character_skill: AnimationPlayer = root.find_child("Skill") as AnimationPlayer
var animation_name: String = "animation_library/%s" % Util.get_resource_name(res)
var animation_name: String = "animation_library/%s" % Util.get_resource_name(res)
if not character_skill.has_animation(animation_name):
print("技能动画不存在:", animation_name)
return

@ -12,14 +12,12 @@ background_mode = 1
sky = SubResource("Sky_hmsea")
ambient_light_source = 2
ambient_light_color = Color(1, 1, 1, 1)
ambient_light_energy = 0.3
ambient_light_energy = 0.2
tonemap_white = 2.39
ssao_enabled = true
ssao_intensity = 1.0
glow_enabled = true
glow_hdr_threshold = 0.8
fog_height = 3.0
fog_height_density = 0.5
volumetric_fog_enabled = true
adjustment_enabled = true
adjustment_contrast = 1.2

@ -1,6 +1,6 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://c8r7kifl8faqr"]
[ext_resource type="Shader" path="res://render/shader/character_silhouette.gdshader" id="2_camhu"]
[ext_resource type="Shader" uid="uid://6h6bjc51jst1" path="res://render/shader/character_silhouette.gdshader" id="2_camhu"]
[resource]
render_priority = 0

@ -1,6 +1,6 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://s5gf3b66luh8"]
[ext_resource type="Shader" path="res://render/shader/character.gdshader" id="1_1ay5b"]
[ext_resource type="Shader" uid="uid://0p40c2iw15lw" path="res://render/shader/character.gdshader" id="1_1ay5b"]
[resource]
render_priority = 1

@ -14,3 +14,4 @@ shader_parameter/focus_min = Vector3(0, 0, 0)
shader_parameter/focus_max = Vector3(0, 0, 0)
shader_parameter/tex_noise1 = ExtResource("2_mif3q")
shader_parameter/tex_noise2 = ExtResource("3_k18qr")
shader_parameter/tex_noise3 = ExtResource("2_mif3q")

@ -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

@ -1,5 +1,4 @@
shader_type spatial;
render_mode depth_prepass_alpha;
uniform sampler2D tex : source_color,filter_nearest;
uniform float flash_white;
@ -27,7 +26,6 @@ void fragment() {
EMISSION = col.rgb * 0.5;
}
ALBEDO = col.rgb;
ALPHA = 1.0;
}
void light() {

@ -7,8 +7,10 @@ uniform vec3 focus_max = vec3(0,0,0);
varying vec3 world_position;
varying vec2 uv1;
varying vec2 uv2;
varying vec2 uv3;
uniform sampler2D tex_noise1 : source_color;
uniform sampler2D tex_noise2 : source_color;
uniform sampler2D tex_noise3 : source_color;
void vertex()
{
@ -16,6 +18,7 @@ void vertex()
vec2 local_uv = vec2(world_position.x,world_position.y + world_position.z);
uv1 = local_uv / 32.0;
uv2 = local_uv / 32.0;
uv3 = local_uv / 8.0;
}
bool is_in_focus(vec3 f_min,vec3 f_max){
@ -54,8 +57,11 @@ void fragment() {
float discrete_noise_value1 = floor(noise_value1 / 0.5) * 0.5;
float noise_value2 = texture(tex_noise2,floor(uv2 /0.02) *0.02).r;
float discrete_noise_value2 = floor(noise_value2 / 0.5) * 0.5;
float noise_value3 = texture(tex_noise3,floor(uv3 /0.02) *0.02).r;
float discrete_noise_value3 = floor(noise_value3 / 0.1) * 0.1;
c -= discrete_noise_value1 * 0.2;
c += discrete_noise_value2 * 0.2;
c -= discrete_noise_value3 * 0.08;
c.rgb = mix(vec3(0.0), c.rgb, brightness);
ALBEDO = c.rgb;
if(is_light){

@ -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,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

@ -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

@ -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

@ -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.

@ -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

@ -135,8 +135,7 @@ layers = 524288
lod_bias = 0.001
gi_mode = 0
pixel_size = 0.02
double_sided = false
texture_filter = 0
alpha_cut = 1
sprite_frames = ExtResource("4_sox5o")
animation = &"fist_skill_special01"
script = ExtResource("4_vijjv")

@ -62,8 +62,6 @@ projection = 1
current = true
size = 7.2
frustum_offset = Vector2(2, 0)
near = 0.1
far = 100.0
script = ExtResource("4_yqiun")
global_effect_curve = SubResource("Curve_f8hvs")

File diff suppressed because one or more lines are too long

@ -1,7 +1,7 @@
[gd_scene load_steps=8 format=3 uid="uid://c342lbsv1d6gi"]
[ext_resource type="Script" path="res://script/level/level_door.gd" id="1_dsgdf"]
[ext_resource type="ArrayMesh" uid="uid://b5asibailmqi8" path="res://resource/mesh_level/m_stone_door1.vox" id="1_rxqyg"]
[ext_resource type="Script" uid="uid://cgf61v6l4pdpb" path="res://script/level/level_door.gd" id="1_dsgdf"]
[ext_resource type="ArrayMesh" uid="uid://clwfvjbys52f6" path="res://resource/mesh_level/chara_active_door01.vox" id="2_p1nra"]
[sub_resource type="BoxShape3D" id="BoxShape3D_unlmt"]
size = Vector3(0.64, 10, 0.64)
@ -113,9 +113,9 @@ tracks/2/keys = {
[sub_resource type="AnimationLibrary" id="AnimationLibrary_8ir0x"]
_data = {
"RESET": SubResource("Animation_24f85"),
"close": SubResource("Animation_ijrpm"),
"open": SubResource("Animation_nrn6r")
&"RESET": SubResource("Animation_24f85"),
&"close": SubResource("Animation_ijrpm"),
&"open": SubResource("Animation_nrn6r")
}
[node name="Door" type="Node3D"]
@ -124,7 +124,7 @@ script = ExtResource("1_dsgdf")
[node name="Mesh" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.28, 0)
visible = false
mesh = ExtResource("1_rxqyg")
mesh = ExtResource("2_p1nra")
[node name="Block" type="StaticBody3D" parent="."]
@ -134,5 +134,5 @@ disabled = true
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": SubResource("AnimationLibrary_8ir0x")
&"": SubResource("AnimationLibrary_8ir0x")
}

@ -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("../..")

@ -136,7 +136,6 @@ func refresh_mesh_library(path_list: Array, from_editor_tool: bool = false):
var reimport_files: Array[String] = []
for file_name_full in path_list:
var mesh_name = file_name_full.get_file().split('-')[0].trim_suffix('.vox')
print(file_name_full)
if not mesh_name.contains("_"):
continue
var name_prefix = mesh_name.split("_")[0]
@ -147,15 +146,16 @@ func refresh_mesh_library(path_list: Array, from_editor_tool: bool = false):
var has_shape: bool
match name_prefix:
"main":
mesh_library = mesh_library_main; mesh_library_id_list=mesh_library_main_id_list; has_material = true; has_shape = true
mesh_library = mesh_library_main; mesh_library_id_list = mesh_library_main_id_list; has_material = true; has_shape = true;
"sub":
mesh_library = mesh_library_sub; mesh_library_id_list = mesh_library_sub_id_list; has_material = true; has_shape = true
mesh_library = mesh_library_sub; mesh_library_id_list = mesh_library_sub_id_list; has_material = true; has_shape = true;
"deco1":
mesh_library = mesh_library_deco1; mesh_library_id_list=mesh_library_deco1_id_list; has_material = true;
mesh_library = mesh_library_deco1; mesh_library_id_list = mesh_library_deco1_id_list; has_material = true;
"deco2":
mesh_library = mesh_library_deco2; mesh_library_id_list=mesh_library_deco2_id_list; has_material = true;
mesh_library = mesh_library_deco2; mesh_library_id_list = mesh_library_deco2_id_list; has_material = true;
"chara":
mesh_library = mesh_library_chara; mesh_library_id_list=mesh_library_chara_id_list
mesh_library = mesh_library_chara; mesh_library_id_list = mesh_library_chara_id_list;
_: continue
var mesh: Mesh = load(file_name_full) as Mesh
var mesh_id: int = mesh_library.find_item_by_name(mesh_name)

@ -71,10 +71,11 @@ func set_body_scale(cfg: CharacterCfg) -> void:
func set_material(material: ShaderMaterial, material_sub: ShaderMaterial):
view.material_override = material
view.material_override.next_pass = material_sub
view.material_override = material_sub
# view.material_override.next_pass = material_sub
#==getter==
func id()->int: return status.id

@ -162,6 +162,8 @@ func update_flip():
func update_view():
position = status.basic_offset + status.shake_offset
# global_position = Util.snap_vector3(global_position)
@ -181,13 +183,16 @@ func _update_material():
var material2: ShaderMaterial = material_override.next_pass as ShaderMaterial
var tex: Texture2D = sprite_frames.get_frame_texture(animation, frame)
var deformation_rate: float = status.deformation_rate * (0.5 if status.is_floating else 0.4)
material2.set_shader_parameter("flash_white", status.flash_white_rate)
material.set_shader_parameter("deformation_dir", status.deformation_dir)
material2.set_shader_parameter("deformation_dir", status.deformation_dir)
material.set_shader_parameter("deformation_rate", deformation_rate)
material2.set_shader_parameter("deformation_rate", deformation_rate)
material.set_shader_parameter("tex", tex)
material2.set_shader_parameter("tex", tex)
if material:
material.set_shader_parameter("flash_white", status.flash_white_rate)
material.set_shader_parameter("deformation_dir", status.deformation_dir)
material.set_shader_parameter("deformation_rate", deformation_rate)
material.set_shader_parameter("tex", tex)
if material2:
material2.set_shader_parameter("flash_white", status.flash_white_rate)
material2.set_shader_parameter("deformation_dir", status.deformation_dir)
material2.set_shader_parameter("deformation_rate", deformation_rate)
material2.set_shader_parameter("tex", tex)
func play_animation(animation_name: String) -> void:

@ -9,7 +9,6 @@ var born_pos: Vector3
func init() -> void:
grid_block_material.set_shader_parameter("is_link", false)
grid_block_material.set_shader_parameter("is_target", true)
grid_block_material.set_shader_parameter("is_focus", true)

@ -2,14 +2,15 @@
extends GridMap
class_name LevelGrid
@export_tool_button("打印item详情", "Callable")
var print_item: Callable = print_item_func
@export_group("替换item_id")
@export var id_from: int = 0
@export var id_to: int = 0
@export_tool_button("替换", "Callable")
var replace_id: Callable = replace_id_func
@export_tool_button("打印item详情", "Callable")
var print_item: Callable = print_item_func
@export_group("整体平移")
@export var translate_dir: Vector3i
@ -25,8 +26,8 @@ func print_item_func ()-> void:
item_count_map[item_id] += 1
else:
item_count_map[item_id] = 1
for item_id in item_count_map:
print("item_id:", item_id, ",count:", item_count_map[item_id])
for item_id: int in item_count_map:
print("[", item_id, "]", mesh_library.get_item_name(item_id), ":", item_count_map[item_id])
func replace_id_func()->void:

@ -2,6 +2,12 @@
extends Node3D
class_name LevelInstance
@export_tool_button("视野锁定", "Callable")
var view_focus_on: Callable = view_focus_on_func
@export_tool_button("视野解锁", "Callable")
var view_focus_off: Callable = view_focus_off_func
@export var size: Vector3i = Vector3i.ONE:
set(value):
if (value.x<1) or (value.y<1) or (value.z<1):
@ -11,6 +17,60 @@ class_name LevelInstance
@export var is_force_battle: bool
@export var enemy_nums: Array[LevelEnemy]
@export_group("替换item_id")
@export var id_from: int = 0
@export var id_to: int = 0
@export_tool_button("替换", "Callable")
var replace_id: Callable = replace_id_func
@export_tool_button("打印item详情", "Callable")
var print_item: Callable = print_item_func
func view_focus_on_func()->void:
grid_block_material.set_shader_parameter("is_focus", true)
set_focus()
func view_focus_off_func()->void:
grid_block_material.set_shader_parameter("is_focus", false)
set_focus()
func replace_id_func()->void:
var level_main: GridMap = %LevelGridMain as GridMap
var id_min: Vector3i = Util.get_level_grid_pos2(pos_min())
var id_max: Vector3i = Util.get_level_grid_pos2(pos_max())
for x in range(id_min.x, id_max.x+1):
for y in range(id_min.y, id_max.y+1):
for z in range(id_min.z, id_max.z+1):
var pos: Vector3i = Vector3i(x, y, z)
if level_main.get_cell_item(pos) == id_from:
level_main.set_cell_item(pos, id_to, level_main.get_cell_item_orientation(pos))
func print_item_func ()-> void:
var level_main: GridMap = %LevelGridMain as GridMap
var id_min: Vector3i = Util.get_level_grid_pos2(pos_min())
var id_max: Vector3i = Util.get_level_grid_pos2(pos_max())
var mesh_library: MeshLibrary = level_main.get_mesh_library()
var item_count_map: Dictionary = {}
for x in range(id_min.x, id_max.x+1):
for y in range(id_min.y, id_max.y+1):
for z in range(id_min.z, id_max.z+1):
var pos: Vector3i = Vector3i(x, y, z)
var item_id: int = level_main.get_cell_item(pos)
if item_id != GridMap.INVALID_CELL_ITEM:
if item_count_map.has(item_id):
item_count_map[item_id] += 1
else:
item_count_map[item_id] = 1
for item_id: int in item_count_map:
print("[", item_id, "]", mesh_library.get_item_name(item_id), ":", item_count_map[item_id])
@onready var grid_block_material: Material = load("res://render/material/level_grid_block.tres") as Material
@ -96,7 +156,7 @@ func init_level_character() -> void:
continue
if pos.z < id_min.z or pos.z > id_max.z:
continue
var float_pos: Vector3 = Util.get_level_float_pos(pos) + Vector3(0.32, 0, 0.32)
var float_pos: Vector3 = Util.get_level_float_pos(pos)
var item_id: int = level_character.get_cell_item(pos)
if item_id == GridMap.INVALID_CELL_ITEM:
continue

@ -0,0 +1,3 @@
extends Node3D
class_name LevelSakura

@ -0,0 +1 @@
uid://5tquxl7cnwr1

@ -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.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save