add blur - fog - dust

This commit is contained in:
Matteo Sonaglioni
2026-03-13 12:59:23 +01:00
parent 83dc8e997c
commit 6801df2103
9 changed files with 317 additions and 79 deletions

View File

@@ -0,0 +1,14 @@
[gd_resource type="ShaderMaterial" format=3 uid="uid://codq5gx71rj4o"]
[ext_resource type="Shader" uid="uid://svdmjppqell5" path="res://Scenes/PolvereAtmosferica.gdshader" id="1_ppnru"]
[resource]
shader = ExtResource("1_ppnru")
shader_parameter/dust_color = Color(0.9999998, 0.7058353, 0.3872684, 0.6)
shader_parameter/wind_velocity = Vector2(-1, -0.5)
shader_parameter/wind_oscillation = 0.0150000007125
shader_parameter/dust_speed = 0.15000000642648
shader_parameter/size_min = 0.010000000475
shader_parameter/size_max = 0.15000000642648
shader_parameter/dust_density = 0.20000000880148
shader_parameter/solid_core = 0.0

17
Scenes/Blur.gdshader Normal file
View File

@@ -0,0 +1,17 @@
shader_type canvas_item;
// Cattura tutto quello che c'è sotto questo nodo
uniform sampler2D screen_texture : hint_screen_texture, filter_linear_mipmap;
uniform float blur_amount : hint_range(0.0, 5.0) = 2.5;
uniform float focus_size : hint_range(0.0, 1.0) = 0.4;
uniform float transition_softness : hint_range(0.01, 1.0) = 0.3;
void fragment() {
float dist_from_center = abs(SCREEN_UV.y - 0.5);
float mask = smoothstep(focus_size / 2.0, (focus_size / 2.0) + transition_softness, dist_from_center);
// Applica il blur
vec4 blurred_screen = textureLod(screen_texture, SCREEN_UV, blur_amount * mask);
COLOR = blurred_screen;
}

1
Scenes/Blur.gdshader.uid Normal file
View File

@@ -0,0 +1 @@
uid://bl1dwh2k06yy5

View File

@@ -7,6 +7,7 @@
[ext_resource type="Texture2D" uid="uid://v4gyjc8j7ygj" path="res://Assets/Textures/Lightingl.png" id="4_gffi5"]
[ext_resource type="Shader" uid="uid://l6rkqonic7dj" path="res://Shaders/Sky.gdshader" id="5_bedag"]
[ext_resource type="PackedScene" uid="uid://bvynwhkogurml" path="res://Godrays_Scene.tscn" id="5_gwrkm"]
[ext_resource type="Material" uid="uid://codq5gx71rj4o" path="res://Materials/Polvere atmosferica.tres" id="5_u10x4"]
[ext_resource type="FastNoiseLite" uid="uid://c0mtwrkptjcuw" path="res://Assets/Textures/Noise_Clouds.tres" id="6_00nhk"]
[ext_resource type="Texture2D" uid="uid://dxahudyvihk8b" path="res://Assets/Textures/Stars.png" id="6_jawsd"]
[ext_resource type="Script" uid="uid://brcimd12tx3dm" path="res://Scripts/edge_detection_compositor.gd" id="7_4xv0h"]
@@ -32,6 +33,7 @@
[ext_resource type="PackedScene" uid="uid://dk85mk0hapngf" path="res://Assets/Test/rock2.glb" id="21_qdxup"]
[ext_resource type="Shader" uid="uid://c0dy1aqj1b4q3" path="res://Shaders/trunk_shader.gdshader" id="22_tbvi6"]
[ext_resource type="Texture2D" uid="uid://8sdgkykyg5l5" path="res://Assets/Textures/rock_color.png" id="23_4udcq"]
[ext_resource type="Shader" uid="uid://b164wpqylv5fo" path="res://Shaders/Fog.gdshader" id="23_u10x4"]
[ext_resource type="PackedScene" uid="uid://jj15telqu3rp" path="res://Scenes/Test/Grass_Test.tscn" id="24_vj0n5"]
[ext_resource type="PackedScene" uid="uid://bioksfn7mydfa" path="res://Assets/Test/Demo/Tree_V2.glb" id="25_00nhk"]
[ext_resource type="Texture2D" uid="uid://cy7kh4dvdd34v" path="res://Assets/Textures/tree_bark.png" id="26_vpybn"]
@@ -45,6 +47,8 @@
[ext_resource type="PackedScene" uid="uid://jqqiendhdgqq" path="res://Scenes/Test/Test_Chunk_Rettilineo.tscn" id="33_mvcuv"]
[ext_resource type="PackedScene" uid="uid://bhcut7ndtdo2w" path="res://Assets/Test/SK_Mannequin.FBX" id="34_3nw1o"]
[ext_resource type="PackedScene" uid="uid://xebpudhewwwj" path="res://Scenes/Chunk_Scene/Chunk/Campagna/Chunk_C_L_2.tscn" id="35_n33lw"]
[ext_resource type="Shader" uid="uid://bl1dwh2k06yy5" path="res://Scenes/Blur.gdshader" id="46_nonqo"]
[ext_resource type="Shader" uid="uid://bttmyh64kihyr" path="res://Scenes/Nebbia2D.gdshader" id="47_7j5hj"]
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_10fbe"]
noise = ExtResource("6_00nhk")
@@ -88,11 +92,11 @@ tonemap_exposure = 1.2
ssil_enabled = true
glow_enabled = true
glow_normalized = true
glow_bloom = 0.5
glow_bloom = 0.35
fog_enabled = true
fog_mode = 1
fog_density = 0.25
fog_aerial_perspective = 0.97
fog_sky_affect = 0.0
volumetric_fog_length = 11.38
volumetric_fog_ambient_inject = 0.27
@@ -230,12 +234,47 @@ sub_emitter_amount_at_collision = 1
material = ExtResource("3_4wepm")
size = Vector2(0.05, 1)
[sub_resource type="CameraAttributesPractical" id="CameraAttributesPractical_gwrkm"]
dof_blur_far_enabled = true
dof_blur_far_distance = 410.0
dof_blur_far_transition = 150.0
dof_blur_near_distance = 0.06
dof_blur_amount = 0.5
[sub_resource type="QuadMesh" id="QuadMesh_jfpsf"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_xjipq"]
render_priority = 0
shader = ExtResource("13_kwbnj")
shader_parameter/billboard_enabled = false
shader_parameter/wind_enabled = false
shader_parameter/base_color = Color(0.21142942, 0.23515752, 0.20549765, 1)
shader_parameter/alpha_texture = ExtResource("16_l1dl0")
shader_parameter/leaves_scale = 1.0
shader_parameter/rotation_degrees = 0.0
shader_parameter/texture_offset = Vector2(0, 0)
shader_parameter/opacity = 1.0
shader_parameter/height_min = 0.0
shader_parameter/height_max = 5.0
shader_parameter/shadow_intensity = 0.0
shader_parameter/highlight_intensity = 0.0
shader_parameter/light_steps = 1.0
shader_parameter/random_mix = 0.0
shader_parameter/cast_shadow_strength = 0.6
[sub_resource type="PlaneMesh" id="PlaneMesh_gsfny"]
[sub_resource type="FastNoiseLite" id="FastNoiseLite_oqwsk"]
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_8vrnd"]
noise = SubResource("FastNoiseLite_oqwsk")
seamless = true
[sub_resource type="ShaderMaterial" id="ShaderMaterial_l1dl0"]
render_priority = 0
shader = ExtResource("23_u10x4")
shader_parameter/fog_noise = SubResource("NoiseTexture2D_8vrnd")
shader_parameter/use_red_as_alpha = true
shader_parameter/fog_color = Color(0.8, 0.8509804, 0.9019608, 1)
shader_parameter/scroll_speed = Vector2(0.01, 0.01)
shader_parameter/texture_scale = Vector2(1, 1)
shader_parameter/edge_softness_y = 0.5
shader_parameter/edge_softness_x = 0.5
shader_parameter/night_intensity = 0.0
shader_parameter/sun_color = Color(1, 1, 1, 1)
[sub_resource type="Curve3D" id="Curve3D_bedag"]
closed = true
@@ -246,9 +285,20 @@ _data = {
}
point_count = 93
[sub_resource type="PlaneMesh" id="PlaneMesh_gsfny"]
[sub_resource type="PlaneMesh" id="PlaneMesh_l1dl0"]
[sub_resource type="QuadMesh" id="QuadMesh_jfpsf"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_kjb07"]
render_priority = 0
shader = ExtResource("23_u10x4")
shader_parameter/fog_noise = SubResource("NoiseTexture2D_8vrnd")
shader_parameter/use_red_as_alpha = true
shader_parameter/fog_color = Color(0.8, 0.8509804, 0.9019608, 0.60784316)
shader_parameter/scroll_speed = Vector2(0.01, 0.01)
shader_parameter/texture_scale = Vector2(0.74, 5)
shader_parameter/edge_softness_y = 0.5
shader_parameter/edge_softness_x = 0.5
shader_parameter/night_intensity = 0.0
shader_parameter/sun_color = Color(1, 1, 1, 1)
[sub_resource type="ShaderMaterial" id="ShaderMaterial_10fbe"]
render_priority = 0
@@ -288,25 +338,6 @@ shader_parameter/light_steps = 1.0
shader_parameter/random_mix = 0.0
shader_parameter/cast_shadow_strength = 0.6
[sub_resource type="ShaderMaterial" id="ShaderMaterial_xjipq"]
render_priority = 0
shader = ExtResource("13_kwbnj")
shader_parameter/billboard_enabled = false
shader_parameter/wind_enabled = false
shader_parameter/base_color = Color(0.21142942, 0.23515752, 0.20549765, 1)
shader_parameter/alpha_texture = ExtResource("16_l1dl0")
shader_parameter/leaves_scale = 1.0
shader_parameter/rotation_degrees = 0.0
shader_parameter/texture_offset = Vector2(0, 0)
shader_parameter/opacity = 1.0
shader_parameter/height_min = 0.0
shader_parameter/height_max = 5.0
shader_parameter/shadow_intensity = 0.0
shader_parameter/highlight_intensity = 0.0
shader_parameter/light_steps = 1.0
shader_parameter/random_mix = 0.0
shader_parameter/cast_shadow_strength = 0.6
[sub_resource type="MultiMesh" id="MultiMesh_twefy"]
transform_format = 1
instance_count = 35
@@ -638,7 +669,20 @@ _surfaces = [{
blend_shape_mode = 0
shadow_mesh = SubResource("ArrayMesh_odcbb")
[node name="DemoForest" type="Node3D" unique_id=265279494]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_u10x4"]
shader = ExtResource("47_7j5hj")
shader_parameter/fog_color = Color(0.85, 0.9, 0.95, 1)
shader_parameter/clear_center_radius = 0.4
shader_parameter/edge_softness = 0.25000001117647996
shader_parameter/max_opacity = 0.150000007125
[sub_resource type="ShaderMaterial" id="ShaderMaterial_kwbnj"]
shader = ExtResource("46_nonqo")
shader_parameter/blur_amount = 0.70000003325
shader_parameter/focus_size = 0.450000021375
shader_parameter/transition_softness = 0.3
[node name="DemoForest" type="Node3D" unique_id=265279494 node_paths=PackedStringArray("nodo_polvere")]
script = ExtResource("1_cr3ar")
color_pomeriggio = Color(0.9999996, 0.6887105, 0.42199263, 1)
color_notte = Color(0.18353948, 0.18552834, 0.48496485, 1)
@@ -648,6 +692,7 @@ energia_luce_notte = 0.998
materiale_nebbia = ExtResource("2_4xv0h")
materiale_pioggia_gocce = ExtResource("3_4wepm")
materiale_nuvole = ExtResource("4_00nhk")
nodo_polvere = NodePath("SubViewportContainer/SubViewport/ScreenEffect/PolvereAtmosferica")
colore_mood_pioggia = Color(0.64196956, 0.72286916, 0.80763674, 1)
colore_fulmine = Color(0.99999946, 0.9857114, 0.46342158, 1)
fulmini_min = 2
@@ -809,9 +854,44 @@ camera_laterale = NodePath("../CameraLaterale")
camera_laterale_2 = NodePath("../CameraLaterale2")
camera_alta = NodePath("../CameraAlta")
[node name="Fondale1" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Camere/CameraPivot" unique_id=1412220944]
transform = Transform3D(-0.11338975, -6.265551, -494.68448, -1.460749, 70.00263, -135.17566, 91.3041, 0.79537505, -2.9306448, -137.96927, 27.780256, 32.44911)
mesh = SubResource("QuadMesh_jfpsf")
skeleton = NodePath("../../../../../..")
surface_material_override/0 = SubResource("ShaderMaterial_xjipq")
[node name="Fondale 2" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Camere/CameraPivot" unique_id=2048931975]
transform = Transform3D(-0.11338975, -6.265551, -494.68448, -1.4607444, 70.002335, -135.17506, 91.3038, 0.7953727, -2.9306355, 74.234314, 28.481268, -18.075485)
mesh = SubResource("QuadMesh_jfpsf")
skeleton = NodePath("../../../../../..")
surface_material_override/0 = SubResource("ShaderMaterial_xjipq")
[node name="Fog" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Camere/CameraPivot" unique_id=1575620825]
transform = Transform3D(-0.00869238, -0.66189253, 16.6858, 0.28842512, 28.96452, 0.8943858, -85.35572, 20.688795, -0.20234364, -31.420975, 5.3996058, 49.11194)
mesh = SubResource("PlaneMesh_gsfny")
skeleton = NodePath("../../../../../..")
surface_material_override/0 = ExtResource("2_4xv0h")
[node name="Fog2" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Camere/CameraPivot" unique_id=567097306]
transform = Transform3D(-0.00869238, -0.66189253, 16.6858, 0.28842497, 28.96451, 0.8943855, -85.35568, 20.688786, -0.20234357, 24.53299, 6.1797442, 49.908123)
mesh = SubResource("PlaneMesh_gsfny")
skeleton = NodePath("../../../../../..")
surface_material_override/0 = ExtResource("2_4xv0h")
[node name="Fog3" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Camere/CameraPivot" unique_id=1510712731]
transform = Transform3D(0.23348677, 23.566315, 10.13246, 0.16955252, 16.852575, -13.287166, -85.35561, 20.688768, -0.20234334, -40.737335, -6.168863, 49.11189)
mesh = SubResource("PlaneMesh_gsfny")
skeleton = NodePath("../../../../../..")
surface_material_override/0 = SubResource("ShaderMaterial_l1dl0")
[node name="Fog4" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Camere/CameraPivot" unique_id=1074990597]
transform = Transform3D(-4.157295, -22.59027, -10.13105, 0.16955031, 16.852552, -13.287153, 85.25453, -21.750288, -0.2636921, 34.739395, -6.168857, 49.111843)
mesh = SubResource("PlaneMesh_gsfny")
skeleton = NodePath("../../../../../..")
surface_material_override/0 = SubResource("ShaderMaterial_l1dl0")
[node name="CameraIso" type="Camera3D" parent="SubViewportContainer/SubViewport/World/Camere/CameraPivot" unique_id=375499667]
transform = Transform3D(0.5778576, -0.57709634, 0.57709634, 0, 0.7071067, 0.7071067, -0.8161376, -0.408607, 0.408607, 231.45, 295, 173.79)
attributes = SubResource("CameraAttributesPractical_gwrkm")
transform = Transform3D(0.5778576, -0.57709634, 0.57709634, 0, 0.7071067, 0.7071067, -0.8161376, -0.408607, 0.408607, 231.45, 290, 173.79)
projection = 1
size = 35.0
near = 0.001
@@ -821,7 +901,7 @@ far = 500.0
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.7547531, 9.898563)
curve = SubResource("Curve3D_bedag")
script = ExtResource("9_isbua")
velocita_treno = 8.0
velocita_treno = 4.0
modello_treno = ExtResource("10_ur7m6")
gruppo_camere = NodePath("../Camere")
modello_traversina = ExtResource("12_nonqo")
@@ -858,11 +938,11 @@ mesh = SubResource("PlaneMesh_gsfny")
skeleton = NodePath("../../../../..")
surface_material_override/0 = ExtResource("2_4xv0h")
[node name="MeshInstance3D20" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Fog" unique_id=1575620825]
transform = Transform3D(0.043454673, -0.010095915, 5.972678e-05, -0.0010768108, -0.1055714, -0.09403253, 0.0018440381, 0.1762621, -0.05631697, -0.21667156, 0.027557772, 2.835077)
mesh = SubResource("PlaneMesh_gsfny")
skeleton = NodePath("../../../../..")
surface_material_override/0 = ExtResource("2_4xv0h")
[node name="MeshInstance3D22" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Fog" unique_id=1444953115]
transform = Transform3D(0.24316195, -0.050508212, 0.0023834452, 0.011936579, 1.027253, 0.15305002, -0.0005505045, -0.035938576, 4.3713703, -0.29843616, 0.06249897, 1.4124649)
visible = false
mesh = SubResource("PlaneMesh_l1dl0")
surface_material_override/0 = SubResource("ShaderMaterial_kjb07")
[node name="MeshInstance3D27" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Fog" unique_id=757807178]
transform = Transform3D(0.023630448, 0.105280176, -6.8980284e-09, 2.182254e-16, -4.603308e-09, -0.15785556, 0.9689784, -0.0025674512, 1.6822005e-10, -0.0900625, 0.02755782, 1.7380874)
@@ -994,14 +1074,8 @@ mesh = SubResource("QuadMesh_jfpsf")
skeleton = NodePath("../../../../..")
surface_material_override/0 = SubResource("ShaderMaterial_xjipq")
[node name="MeshInstance3D26" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Fondali" unique_id=1412220944]
transform = Transform3D(0.087180555, -0.011552672, -0.9327844, -0.0035826832, 0.08077537, -0.15448467, 0.2480174, 0.0052277013, 0.3256512, -0.3361349, -0.34356952, 0.416931)
mesh = SubResource("QuadMesh_jfpsf")
skeleton = NodePath("../../../../..")
surface_material_override/0 = SubResource("ShaderMaterial_xjipq")
[node name="MeshInstance3D27" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/World/Fondali" unique_id=1494524637]
transform = Transform3D(0.26267588, 0.0016141435, 0.038116224, -0.0035826885, 0.080775365, -0.15448464, -0.010702037, 0.0125772655, 0.98726016, -0.22054955, -0.34356952, 0.6679051)
transform = Transform3D(0.26267588, 0.0016141436, 0.038116224, -0.0035826885, 0.080775365, -0.15448464, -0.010702038, 0.012577266, 0.9872602, -0.22054955, -0.34356952, 0.6950124)
mesh = SubResource("QuadMesh_jfpsf")
skeleton = NodePath("../../../../..")
surface_material_override/0 = SubResource("ShaderMaterial_xjipq")
@@ -20727,6 +20801,42 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.7385445, 0, 43.8387)
[node name="SK_Mannequin2" parent="SubViewportContainer/SubViewport/World" unique_id=24662648 instance=ExtResource("34_3nw1o")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.9180713, 0, 29.270012)
[node name="ScreenEffect" type="CanvasLayer" parent="SubViewportContainer/SubViewport" unique_id=1639236585]
layer = 2
[node name="PolvereAtmosferica" type="ColorRect" parent="SubViewportContainer/SubViewport/ScreenEffect" unique_id=263223022]
material = ExtResource("5_u10x4")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="ScreenEffect2" type="CanvasLayer" parent="SubViewportContainer/SubViewport" unique_id=2088057254]
layer = 3
[node name="Nebbia" type="ColorRect" parent="SubViewportContainer/SubViewport/ScreenEffect2" unique_id=1102385319]
material = SubResource("ShaderMaterial_u10x4")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="ScreenEffect3" type="CanvasLayer" parent="SubViewportContainer/SubViewport" unique_id=301859382]
layer = 4
[node name="Blur" type="ColorRect" parent="SubViewportContainer/SubViewport/ScreenEffect3" unique_id=2000734182]
material = SubResource("ShaderMaterial_kwbnj")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[editable path="SubViewportContainer/SubViewport/World/Blockout_1/Mare/rock25"]
[editable path="SubViewportContainer/SubViewport/World/Blockout_1/Tree2/Trees/tree2"]
[editable path="SubViewportContainer/SubViewport/World/Blockout_1/Tree2/Trees/tree3"]

29
Scenes/Nebbia2D.gdshader Normal file
View File

@@ -0,0 +1,29 @@
shader_type canvas_item;
// Colore della tua nebbia (scegli un colore che stia bene col tuo Skybox)
uniform vec4 fog_color : source_color = vec4(0.85, 0.9, 0.95, 1.0);
// Quanto è grande lo spazio pulito al centro per il treno
uniform float clear_center_radius : hint_range(0.0, 1.0) = 0.4;
// Quanto è morbida la sfumatura della nebbia verso i bordi
uniform float edge_softness : hint_range(0.01, 1.0) = 0.5;
// Opacità massima ai bordi estremi dello schermo
uniform float max_opacity : hint_range(0.0, 1.0) = 0.8;
void fragment() {
// Calcola la distanza del pixel dal centro dello schermo (0.5, 0.5)
float dist_from_center = distance(SCREEN_UV, vec2(0.5));
// Crea una maschera morbida circolare
// Al centro (distanza < clear_center) sarà 0.0 (trasparente)
// Verso i bordi salirà dolcemente fino a 1.0 (opaco)
float fog_amount = smoothstep(clear_center_radius, clear_center_radius + edge_softness, dist_from_center);
// Moltiplica per l'opacità massima desiderata
fog_amount *= max_opacity;
// Applica il colore della nebbia solo dove serve
COLOR = vec4(fog_color.rgb, fog_color.a * fog_amount);
}

View File

@@ -0,0 +1 @@
uid://bttmyh64kihyr

View File

@@ -0,0 +1,85 @@
shader_type canvas_item;
uniform sampler2D screen_texture : hint_screen_texture, filter_linear_mipmap;
// --- 1. COLORE E VISIBILITÀ ---
// Ho alzato un po' l'Alpha base per renderli più visibili fin da subito
uniform vec4 dust_color : source_color = vec4(1.0, 0.9, 0.7, 0.6);
// --- 2. VENTO E MOVIMENTO ---
// X negativo = verso sinistra. Y positivo = verso il basso.
uniform vec2 wind_velocity = vec2(-0.2, 0.05);
uniform float wind_oscillation : hint_range(0.0, 1.0) = 0.3;
uniform float dust_speed : hint_range(0.01, 1.0) = 0.15;
// --- 3. DIMENSIONI E DENSITÀ ---
uniform float size_min : hint_range(0.001, 0.1) = 0.02;
uniform float size_max : hint_range(0.01, 0.5) = 0.2;
uniform float dust_density : hint_range(0.01, 10.0) = 1.0;
// --- 4. IL FIX DEL CENTRO (Morbidezza) ---
// 0.0 = Sfumatura totale dal centro esatto fino al bordo.
// 0.5 = Metà pallino è solido, l'altra metà sfuma.
// 0.9 = Pallino dai bordi durissimi.
uniform float solid_core : hint_range(0.0, 0.99) = 0.1;
vec3 hash33(vec3 p3) {
p3 = fract(p3 * vec3(0.1031, 0.1030, 0.0973));
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.xxy + p3.yzz) * p3.zyx);
}
void fragment() {
vec4 scene_color = texture(screen_texture, SCREEN_UV);
float base_time = TIME * dust_speed;
// Vento con oscillazione naturale
vec2 osc = vec2(sin(TIME * 0.5), cos(TIME * 0.3)) * wind_oscillation;
vec2 final_wind = (wind_velocity + osc) * dust_speed;
float final_particle_alpha = 0.0;
// Configurazione dei 3 strati (Vicino, Medio, Lontano)
vec3 layer_scales = vec3(20.0, 50.0, 100.0) / dust_density;
vec3 layer_thresholds = vec3(0.96, 0.98, 0.99);
vec3 layer_speeds = vec3(1.0, 0.6, 0.3);
for (int i = 0; i < 3; i++) {
float scale = layer_scales[i];
float threshold = layer_thresholds[i];
float speed_mult = layer_speeds[i];
// Spostiamo la griglia con il vento
vec2 st = (SCREEN_UV * scale) - (final_wind * speed_mult * base_time * 50.0);
vec2 ipos = floor(st);
vec2 fpos = fract(st);
vec3 rand = hash33(vec3(ipos, float(i)));
if (rand.z > threshold) {
// Effetto brillio
float blink = sin(TIME * (2.0 + rand.x)) * 0.5 + 0.5;
float d = length(fpos - vec2(0.5));
float size = size_min + (size_max - size_min) * rand.x;
float scaled_size = size * (0.5 + 0.5 * blink);
// --- LA SOLUZIONE "ANTI-CIAMBELLA" ---
// Calcoliamo la grandezza del "nucleo solido" in proporzione alla grandezza totale.
float core = scaled_size * solid_core;
// Se la distanza (d) è minore del 'core', l'opacità è 1.0.
// Se va dal 'core' fino al bordo (scaled_size), sfuma dolcemente verso lo 0.0.
float particle_softness = 1.0 - smoothstep(core, scaled_size, d);
// Uniamo tutto: morbidezza, brillio, e una correzione per l'intensità in base allo strato
float intensity = (rand.z - threshold) / (1.0 - threshold);
final_particle_alpha += particle_softness * blink * intensity;
}
}
final_particle_alpha = clamp(final_particle_alpha, 0.0, 1.0);
vec4 dust_colored_particle = dust_color * final_particle_alpha;
COLOR = scene_color + dust_colored_particle;
}

View File

@@ -0,0 +1 @@
uid://svdmjppqell5

View File

@@ -24,6 +24,8 @@ extends Node3D
@export var materiale_nebbia: ShaderMaterial
@export var materiale_pioggia_gocce: StandardMaterial3D
@export var materiale_nuvole: ShaderMaterial
# --- NUOVO: SLOT NODO POLVERE ---
@export var nodo_polvere: ColorRect
@export_group("Meteo (Pioggia & Fulmini)")
@export var colore_mood_pioggia: Color = Color(0.5, 0.6, 0.7, 1.0)
@@ -38,23 +40,13 @@ extends Node3D
@export_group("Cinematic Mode Ambiente")
@export var intervallo_eventi_meteo: float = 8.0
# --- NUOVO: PARAMETRI GOD RAYS ---
@export_group("God Rays")
@export var godray_scene: PackedScene
@export var max_rain_godrays: int = 8
@export var godray_spawn_radius: float = 15.0
# --- NUOVE VARIABILI PER L'ISOMETRICA ---
# Sposta il centro in cui nascono i raggi (es. più a destra e più in alto)
@export var godray_spawn_offset: Vector3 = Vector3(15.0, 5.0, -15.0)
# Incliniamo i raggi per farli spiovere dall'alto a destra.
# (X negativa li inclina in avanti, Z li fa "stendere" diagonalmente sullo schermo)
@export var godray_rotation_degrees: Vector3 = Vector3(-45.0, 45.0, -30.0)
# Quanto in alto rispetto al suolo/treno devono nascere
@export var godray_spawn_height: float = 5.0
# Quanto devono essere lunghi i raggi (scala Y) e larghi (scala X)
@export var godray_scale: Vector3 = Vector3(2.0, 6.0, 2.0)
@onready var sole: DirectionalLight3D = $DirectionalLight3D
@@ -62,10 +54,7 @@ extends Node3D
@onready var menu_giornata: OptionButton = $CanvasLayer/OptionButton
@onready var bottone_pioggia: CheckButton = $CanvasLayer/CheckButtonPioggia
@onready var particelle_pioggia: GPUParticles3D = $SubViewportContainer/SubViewport/World/Camere/PioggiaCadente
# --- NUOVO: RIFERIMENTO AL NODO DELLE CAMERE PER FARLI MUOVERE COL TRENO ---
@onready var nodo_camere: Node3D = $SubViewportContainer/SubViewport/World/Camere
@onready var luce_lampo: DirectionalLight3D = $LuceLampo
@onready var sprite_fulmine: Sprite3D = $SubViewportContainer/SubViewport/World/Camere/SpriteFulmine
@@ -123,7 +112,6 @@ func _on_giornata_selezionata(index: int) -> void:
tween_giorno.set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
tween_giorno.tween_property(self, "tempo_giorno", target_tempo, durata_transizione)
# --- NUOVO: SE E' MATTINA (Index 0), SPAWNA IL GODRAY ---
if index == 0:
trigger_morning()
@@ -132,14 +120,11 @@ func _on_pioggia_toggled(toggled_on: bool) -> void:
is_cinematic_mode = false
print("Ambiente Cinematic: DISATTIVATA (Pioggia cambiata manualmente)")
# --- NUOVO: SALVIAMO LO STATO PRECEDENTE PER CAPIRE SE HA SMESSO ---
var stava_piovendo = is_raining
is_raining = toggled_on
if particelle_pioggia:
particelle_pioggia.emitting = is_raining
# --- NUOVO: SE STAVA PIOVENDO E ORA NON PIOVE PIÙ, SPAWNA TANTI GODRAYS ---
if stava_piovendo and not is_raining:
trigger_after_rain()
@@ -213,6 +198,18 @@ func _process(delta: float) -> void:
materiale_nebbia.set_shader_parameter("night_intensity", night_val)
materiale_nebbia.set_shader_parameter("sun_color", final_tint)
# ==========================================
# --- NUOVO: GESTIONE POLVERE INFALLIBILE ---
# ==========================================
if nodo_polvere:
var e_notte = tempo_giorno >= 2.5
# Accende/Spegne brutalmente il nodo
if not is_raining and not e_notte:
nodo_polvere.visible = true
else:
nodo_polvere.visible = false
func _genera_evento_meteo_casuale() -> void:
sto_cambiando_in_cinematic = true
@@ -275,16 +272,10 @@ func _scatena_fulmine() -> void:
if numero_scariche > 1:
await get_tree().create_timer(randf_range(0.05, 0.15)).timeout
# ==========================================
# --- FUNZIONI GOD RAYS INTEGRATE ---
# ==========================================
func trigger_morning() -> void:
# Quando è mattina spara un solo godray vicino al treno
spawn_single_godray()
func trigger_after_rain() -> void:
# Evitiamo di farli spawnare se piove di notte (tempo_giorno >= 2.5)
if tempo_giorno < 2.5:
for i in range(max_rain_godrays):
spawn_single_godray()
@@ -299,23 +290,12 @@ func spawn_single_godray() -> void:
var ray = godray_scene.instantiate()
# --- LA MAGIA È QUI ---
# Invece di aggiungerli a "nodo_camere" (che si muove),
# li aggiungiamo al genitore delle camere (il nodo "World"), che è fermo!
var nodo_mondo = nodo_camere.get_parent()
nodo_mondo.add_child(ray)
# Calcoliamo una posizione casuale
var random_x = randf_range(-godray_spawn_radius, godray_spawn_radius)
var random_z = randf_range(-godray_spawn_radius, godray_spawn_radius)
# Usiamo la GLOBAL_POSITION: Il raggio prende le coordinate globali di dov'è la
# telecamera in QUESTO preciso millisecondo, e ci aggiunge il suo offset casuale.
# Da questo momento in poi, essendo figlio del Mondo, resterà immobile lì.
ray.global_position = nodo_camere.global_position + Vector3(random_x, godray_spawn_height, random_z)
# Li incliniamo tutti uguali per farli piovere dall'angolo
ray.rotation_degrees = godray_rotation_degrees
# Li allunghiamo per farli sembrare veri fasci di luce
ray.scale = godray_scale