clean
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
[gd_scene format=3 uid="uid://bvynwhkogurml"]
|
[gd_scene format=3 uid="uid://bvynwhkogurml"]
|
||||||
|
|
||||||
[ext_resource type="PlaneMesh" uid="uid://djremrthsiasg" path="res://Assets/Meshes/Godrays.tres" id="1_ua621"]
|
[ext_resource type="PlaneMesh" uid="uid://djremrthsiasg" path="res://Assets/Meshes/Godrays.tres" id="1_ua621"]
|
||||||
[ext_resource type="Script" uid="uid://duu1t8cjm12oi" path="res://GodrayBurst.gd" id="1_viats"]
|
[ext_resource type="Script" uid="uid://duu1t8cjm12oi" path="res://Scripts/GodrayBurst.gd" id="1_viats"]
|
||||||
[ext_resource type="Material" uid="uid://cwbxvmtih5wsc" path="res://Materials/GodRays.tres" id="2_ua621"]
|
[ext_resource type="Material" uid="uid://cwbxvmtih5wsc" path="res://Materials/GodRays.tres" id="2_ua621"]
|
||||||
|
|
||||||
[node name="Node3D" type="MeshInstance3D" unique_id=1364530594]
|
[node name="Node3D" type="MeshInstance3D" unique_id=1364530594]
|
||||||
@@ -10,6 +10,7 @@ shader_parameter/albedo_color = Color(0.76525277, 0.97499627, 0.42436218, 1)
|
|||||||
shader_parameter/albedo_texture = ExtResource("2_ssxga")
|
shader_parameter/albedo_texture = ExtResource("2_ssxga")
|
||||||
shader_parameter/use_texture = true
|
shader_parameter/use_texture = true
|
||||||
shader_parameter/uv_scale = Vector2(1, 1)
|
shader_parameter/uv_scale = Vector2(1, 1)
|
||||||
|
shader_parameter/palette_shift_y = 0.0
|
||||||
shader_parameter/light_steps = 3.0
|
shader_parameter/light_steps = 3.0
|
||||||
shader_parameter/step_softness = 0.1
|
shader_parameter/step_softness = 0.1
|
||||||
shader_parameter/shadow_color = Color(0.4, 0.4, 0.6, 1)
|
shader_parameter/shadow_color = Color(0.4, 0.4, 0.6, 1)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ render_priority = 0
|
|||||||
shader = ExtResource("1_2uy3m")
|
shader = ExtResource("1_2uy3m")
|
||||||
shader_parameter/billboard_enabled = true
|
shader_parameter/billboard_enabled = true
|
||||||
shader_parameter/wind_enabled = true
|
shader_parameter/wind_enabled = true
|
||||||
shader_parameter/base_color = Color(0.2, 0.6, 0.3, 1)
|
shader_parameter/base_color = Color(0.8963595, 0.48646247, 0.64866394, 1)
|
||||||
shader_parameter/alpha_texture = ExtResource("2_2uy3m")
|
shader_parameter/alpha_texture = ExtResource("2_2uy3m")
|
||||||
shader_parameter/leaves_scale = 1.375
|
shader_parameter/leaves_scale = 1.375
|
||||||
shader_parameter/rotation_degrees = 180.0
|
shader_parameter/rotation_degrees = 180.0
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[ext_resource type="Material" uid="uid://cknq8qhom7ral" path="res://Materials/ShadowPostProcess.tres" id="4_00nhk"]
|
[ext_resource type="Material" uid="uid://cknq8qhom7ral" path="res://Materials/ShadowPostProcess.tres" id="4_00nhk"]
|
||||||
[ext_resource type="Texture2D" uid="uid://v4gyjc8j7ygj" path="res://Assets/Textures/Lightingl.png" id="4_gffi5"]
|
[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="Shader" uid="uid://l6rkqonic7dj" path="res://Shaders/Sky.gdshader" id="5_bedag"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bvynwhkogurml" path="res://Scenes/Godrays_Scene.tscn" id="5_gwrkm"]
|
[ext_resource type="PackedScene" uid="uid://bvynwhkogurml" path="res://Godrays_Scene.tscn" id="5_gwrkm"]
|
||||||
[ext_resource type="FastNoiseLite" uid="uid://c0mtwrkptjcuw" path="res://Assets/Textures/Noise_Clouds.tres" id="6_00nhk"]
|
[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="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"]
|
[ext_resource type="Script" uid="uid://brcimd12tx3dm" path="res://Scripts/edge_detection_compositor.gd" id="7_4xv0h"]
|
||||||
@@ -704,13 +704,12 @@ offset_bottom = 3.0
|
|||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
stretch = true
|
stretch = true
|
||||||
stretch_shrink = 3
|
|
||||||
mouse_target = true
|
mouse_target = true
|
||||||
|
|
||||||
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer" unique_id=1099909885]
|
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer" unique_id=1099909885]
|
||||||
handle_input_locally = false
|
handle_input_locally = false
|
||||||
canvas_item_default_texture_filter = 0
|
canvas_item_default_texture_filter = 0
|
||||||
size = Vector2i(384, 216)
|
size = Vector2i(1152, 648)
|
||||||
render_target_update_mode = 4
|
render_target_update_mode = 4
|
||||||
|
|
||||||
[node name="World" type="Node3D" parent="SubViewportContainer/SubViewport" unique_id=735268770]
|
[node name="World" type="Node3D" parent="SubViewportContainer/SubViewport" unique_id=735268770]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[gd_scene format=3 uid="uid://h63qncgtdqpi"]
|
[gd_scene format=3 uid="uid://h63qncgtdqpi"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://qpix2kjcwpg" path="res://Assets/Test/Casetta_Blockout.fbx" id="1_nu2bs"]
|
[ext_resource type="PackedScene" uid="uid://qpix2kjcwpg" path="res://Assets/Test/Casetta_Blockout.fbx" id="1_nu2bs"]
|
||||||
[ext_resource type="Material" uid="uid://da8erd0d83kog" path="res://Shaders/Palette_Cel.tres" id="2_nu2bs"]
|
[ext_resource type="Material" uid="uid://da8erd0d83kog" path="res://Materials/Palette_Cel.tres" id="2_nu2bs"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cdlgd0h5qeb7k" path="res://Assets/Textures/Palette_train.png" id="3_802us"]
|
[ext_resource type="Texture2D" uid="uid://cdlgd0h5qeb7k" path="res://Assets/Textures/Palette_train.png" id="3_802us"]
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_buxff"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_buxff"]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[gd_scene format=3 uid="uid://4iye3qapad4y"]
|
[gd_scene format=3 uid="uid://4iye3qapad4y"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://dopxtbmauwr0n" path="res://Assets/Test/Colonnina_Blockout.fbx" id="1_iaqs2"]
|
[ext_resource type="PackedScene" uid="uid://dopxtbmauwr0n" path="res://Assets/Test/Colonnina_Blockout.fbx" id="1_iaqs2"]
|
||||||
[ext_resource type="Material" uid="uid://da8erd0d83kog" path="res://Shaders/Palette_Cel.tres" id="2_hqihs"]
|
[ext_resource type="Material" uid="uid://da8erd0d83kog" path="res://Materials/Palette_Cel.tres" id="2_hqihs"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cdlgd0h5qeb7k" path="res://Assets/Textures/Palette_train.png" id="3_jfj3v"]
|
[ext_resource type="Texture2D" uid="uid://cdlgd0h5qeb7k" path="res://Assets/Textures/Palette_train.png" id="3_jfj3v"]
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_6tlqt"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_6tlqt"]
|
||||||
|
|||||||
17
Scenes/test_no_roof.tscn
Normal file
17
Scenes/test_no_roof.tscn
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[gd_scene format=3 uid="uid://bdhphg2oi4n1v"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bbdaxcrf48xsr" path="res://Assets/Meshes/House/Test_NoRoof.fbx" id="1_k6nmq"]
|
||||||
|
[ext_resource type="Material" uid="uid://biaudrjlfoflm" path="res://Materials/House.tres" id="2_si57c"]
|
||||||
|
|
||||||
|
[node name="Test_NoRoof" unique_id=1047340045 instance=ExtResource("1_k6nmq")]
|
||||||
|
|
||||||
|
[node name="Cube_005" parent="." index="0" unique_id=1082356799]
|
||||||
|
surface_material_override/0 = ExtResource("2_si57c")
|
||||||
|
surface_material_override/1 = ExtResource("2_si57c")
|
||||||
|
surface_material_override/2 = ExtResource("2_si57c")
|
||||||
|
surface_material_override/3 = ExtResource("2_si57c")
|
||||||
|
surface_material_override/4 = ExtResource("2_si57c")
|
||||||
|
surface_material_override/5 = ExtResource("2_si57c")
|
||||||
|
surface_material_override/6 = ExtResource("2_si57c")
|
||||||
|
surface_material_override/7 = ExtResource("2_si57c")
|
||||||
|
surface_material_override/8 = ExtResource("2_si57c")
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends MultiMeshInstance3D
|
|
||||||
|
|
||||||
@export var mesh_volume: MeshInstance3D : # Trascina qui il tuo volume low poly
|
|
||||||
set(val):
|
|
||||||
mesh_volume = val
|
|
||||||
generate_leaves()
|
|
||||||
|
|
||||||
@export var scale_multiplier: float = 1.5 # Per rendere i piani grandi come in foto
|
|
||||||
|
|
||||||
func generate_leaves():
|
|
||||||
if not mesh_volume or not mesh_volume.mesh:
|
|
||||||
return
|
|
||||||
|
|
||||||
var mdt = MeshDataTool.new()
|
|
||||||
mdt.create_from_surface(mesh_volume.mesh, 0)
|
|
||||||
|
|
||||||
var face_count = mdt.get_face_count()
|
|
||||||
|
|
||||||
# Inizializza il MultiMesh
|
|
||||||
multimesh.instance_count = face_count
|
|
||||||
|
|
||||||
for i in range(face_count):
|
|
||||||
# 1. Trova il centro della faccia
|
|
||||||
var v1 = mdt.get_vertex(mdt.get_face_vertex(i, 0))
|
|
||||||
var v2 = mdt.get_vertex(mdt.get_face_vertex(i, 1))
|
|
||||||
var v3 = mdt.get_vertex(mdt.get_face_vertex(i, 2))
|
|
||||||
var center = (v1 + v2 + v3) / 3.0
|
|
||||||
|
|
||||||
# 2. Ottieni la normale della faccia per orientare il piano
|
|
||||||
var normal = mdt.get_face_normal(i)
|
|
||||||
|
|
||||||
# 3. Crea la trasformazione
|
|
||||||
# Usiamo 'look_at' per far sì che il piano sia parallelo alla faccia
|
|
||||||
var pos = center
|
|
||||||
var target = pos + normal
|
|
||||||
var xform = Transform3D().looking_at(normal, Vector3.UP)
|
|
||||||
|
|
||||||
# Applichiamo posizione e scala
|
|
||||||
xform.origin = pos
|
|
||||||
xform = xform.scaled(Vector3.ONE * scale_multiplier)
|
|
||||||
|
|
||||||
# 4. Applica al MultiMesh
|
|
||||||
multimesh.set_instance_transform(i, xform)
|
|
||||||
|
|
||||||
# Opzionale: nascondi il volume originale se vuoi vedere solo i piani
|
|
||||||
# mesh_volume.visible = false
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://dxgc5kjl1048
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
extends Path3D
|
|
||||||
|
|
||||||
@export_group("Impostazioni Treno")
|
|
||||||
@export var velocita_treno: float = 6.0
|
|
||||||
@export var in_movimento: bool = true
|
|
||||||
|
|
||||||
@export_group("Costruzione Rotaie")
|
|
||||||
@export var distanza_traversine: float = 1.0 # Ogni quanti metri mettere un asse di legno
|
|
||||||
|
|
||||||
var nodo_treno: PathFollow3D
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
# Controlla se hai disegnato il percorso
|
|
||||||
if curve == null or curve.get_baked_length() == 0:
|
|
||||||
print("ATTENZIONE: Devi prima disegnare i punti del Path3D!")
|
|
||||||
return
|
|
||||||
|
|
||||||
_costruisci_rotaie_da_zero()
|
|
||||||
_costruisci_treno_da_zero()
|
|
||||||
|
|
||||||
func _costruisci_rotaie_da_zero() -> void:
|
|
||||||
# 1. Creiamo i materiali (Colori) per le rotaie
|
|
||||||
var mat_legno = StandardMaterial3D.new()
|
|
||||||
mat_legno.albedo_color = Color(0.35, 0.2, 0.1) # Marrone scuro
|
|
||||||
|
|
||||||
var mat_ferro = StandardMaterial3D.new()
|
|
||||||
mat_ferro.albedo_color = Color(0.6, 0.6, 0.65) # Grigio metallico
|
|
||||||
mat_ferro.metallic = 0.8
|
|
||||||
|
|
||||||
# 2. Creiamo le forme geometriche base (Box)
|
|
||||||
var mesh_traversina = BoxMesh.new()
|
|
||||||
mesh_traversina.size = Vector3(1.8, 0.1, 0.3)
|
|
||||||
|
|
||||||
var mesh_binario = BoxMesh.new()
|
|
||||||
# La lunghezza del binario è uguale alla distanza tra le traversine per connettersi perfettamente
|
|
||||||
mesh_binario.size = Vector3(0.1, 0.15, distanza_traversine + 0.05)
|
|
||||||
|
|
||||||
# 3. Calcoliamo quanti pezzi servono
|
|
||||||
var lunghezza_totale = curve.get_baked_length()
|
|
||||||
var numero_pezzi = int(lunghezza_totale / distanza_traversine)
|
|
||||||
|
|
||||||
# 4. Piazziamo i pezzi lungo la curva
|
|
||||||
for i in range(numero_pezzi):
|
|
||||||
var distanza = i * distanza_traversine
|
|
||||||
var transform_punto = curve.sample_baked_with_rotation(distanza, true, true)
|
|
||||||
|
|
||||||
# Nodo "Pezzo" che fa da raggruppamento
|
|
||||||
var pezzo_binario = Node3D.new()
|
|
||||||
pezzo_binario.transform = transform_punto
|
|
||||||
add_child(pezzo_binario)
|
|
||||||
|
|
||||||
# Creiamo la traversina in legno
|
|
||||||
var traversina = MeshInstance3D.new()
|
|
||||||
traversina.mesh = mesh_traversina
|
|
||||||
traversina.material_override = mat_legno
|
|
||||||
pezzo_binario.add_child(traversina)
|
|
||||||
|
|
||||||
# Creiamo il binario sinistro
|
|
||||||
var binario_sx = MeshInstance3D.new()
|
|
||||||
binario_sx.mesh = mesh_binario
|
|
||||||
binario_sx.material_override = mat_ferro
|
|
||||||
binario_sx.position = Vector3(-0.6, 0.1, 0) # Spostato a sinistra e leggermente in alto
|
|
||||||
pezzo_binario.add_child(binario_sx)
|
|
||||||
|
|
||||||
# Creiamo il binario destro
|
|
||||||
var binario_dx = MeshInstance3D.new()
|
|
||||||
binario_dx.mesh = mesh_binario
|
|
||||||
binario_dx.material_override = mat_ferro
|
|
||||||
binario_dx.position = Vector3(0.6, 0.1, 0) # Spostato a destra e leggermente in alto
|
|
||||||
pezzo_binario.add_child(binario_dx)
|
|
||||||
|
|
||||||
|
|
||||||
func _costruisci_treno_da_zero() -> void:
|
|
||||||
# 1. Creiamo il PathFollow che gestisce il movimento
|
|
||||||
nodo_treno = PathFollow3D.new()
|
|
||||||
nodo_treno.rotation_mode = PathFollow3D.ROTATION_Y # IMPORTANTE: Evita che il treno si inclini di lato
|
|
||||||
nodo_treno.cubic_interp = false # Rende la velocità costante ed elimina i tremolii
|
|
||||||
nodo_treno.loop = true
|
|
||||||
add_child(nodo_treno)
|
|
||||||
|
|
||||||
# 2. Materiali del treno
|
|
||||||
var mat_carrozzeria = StandardMaterial3D.new()
|
|
||||||
mat_carrozzeria.albedo_color = Color(0.8, 0.15, 0.15) # Rosso acceso
|
|
||||||
|
|
||||||
var mat_vetro = StandardMaterial3D.new()
|
|
||||||
mat_vetro.albedo_color = Color(0.2, 0.8, 1.0) # Azzurro
|
|
||||||
|
|
||||||
# 3. Costruiamo la Base del treno
|
|
||||||
var base_treno = MeshInstance3D.new()
|
|
||||||
var mesh_base = BoxMesh.new()
|
|
||||||
mesh_base.size = Vector3(1.4, 0.8, 3.0)
|
|
||||||
base_treno.mesh = mesh_base
|
|
||||||
base_treno.material_override = mat_carrozzeria
|
|
||||||
base_treno.position = Vector3(0, 0.6, 0) # Alzato per stare sopra le rotaie
|
|
||||||
nodo_treno.add_child(base_treno)
|
|
||||||
|
|
||||||
# 4. Costruiamo la Cabina del macchinista
|
|
||||||
var cabina = MeshInstance3D.new()
|
|
||||||
var mesh_cabina = BoxMesh.new()
|
|
||||||
mesh_cabina.size = Vector3(1.4, 1.0, 1.2)
|
|
||||||
cabina.mesh = mesh_cabina
|
|
||||||
cabina.material_override = mat_vetro
|
|
||||||
cabina.position = Vector3(0, 1.5, -0.8) # Messa dietro e in alto
|
|
||||||
nodo_treno.add_child(cabina)
|
|
||||||
|
|
||||||
# 5. Costruiamo la Ciminiera (davanti)
|
|
||||||
var ciminiera = MeshInstance3D.new()
|
|
||||||
var mesh_ciminiera = CylinderMesh.new()
|
|
||||||
mesh_ciminiera.top_radius = 0.2
|
|
||||||
mesh_ciminiera.bottom_radius = 0.3
|
|
||||||
mesh_ciminiera.height = 0.8
|
|
||||||
ciminiera.mesh = mesh_ciminiera
|
|
||||||
ciminiera.material_override = mat_carrozzeria
|
|
||||||
ciminiera.position = Vector3(0, 1.2, 1.0)
|
|
||||||
nodo_treno.add_child(ciminiera)
|
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
# Se in movimento, fa avanzare automaticamente il nodo_treno lungo la curva
|
|
||||||
if in_movimento and nodo_treno:
|
|
||||||
nodo_treno.progress += velocita_treno * delta
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://c2ec8k6lbx5cb
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
extends GPUParticles3D
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
# Quando spawna, emette le particelle
|
|
||||||
emitting = true
|
|
||||||
# Si autodistrugge dopo che le particelle sono svanite
|
|
||||||
await get_tree().create_timer(lifetime + 0.5).timeout
|
|
||||||
queue_free()
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://c1wwiocqnv0qs
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
extends Node3D
|
|
||||||
|
|
||||||
signal mappa_pronta
|
|
||||||
|
|
||||||
@export_group("Impostazioni Mappa")
|
|
||||||
@export var dimensione_chunk: float = 10.0
|
|
||||||
@export var lunghezza_percorso: int = 15
|
|
||||||
@export var larghezza_bioma: int = 5
|
|
||||||
@export var OFFSET_ROTATION: float = 0.0 # Regola qui se i pezzi nascono storti
|
|
||||||
|
|
||||||
@export_group("Cataloghi")
|
|
||||||
@export var scena_dritto: PackedScene
|
|
||||||
@export var scena_curva: PackedScene
|
|
||||||
@export var catalogo_bioma: Array[PackedScene]
|
|
||||||
|
|
||||||
@export var path_treno: Path3D
|
|
||||||
|
|
||||||
var mappa_virtuale: Dictionary = {}
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
mappa_virtuale.clear()
|
|
||||||
if path_treno and path_treno.curve:
|
|
||||||
path_treno.curve.clear_points()
|
|
||||||
|
|
||||||
if scena_dritto and scena_curva:
|
|
||||||
_genera_tutto()
|
|
||||||
else:
|
|
||||||
print("MANCANO GLI ASSET NELL'INSPECTOR!")
|
|
||||||
|
|
||||||
func _genera_tutto() -> void:
|
|
||||||
_genera_binari()
|
|
||||||
_genera_bioma()
|
|
||||||
emit_signal("mappa_pronta")
|
|
||||||
|
|
||||||
# --- FASE 1: I BINARI (Logica 3x3) ---
|
|
||||||
func _genera_binari() -> void:
|
|
||||||
var pos_corrente = Vector2i(0, 0)
|
|
||||||
var dir_corrente = Vector2i(0, -1) # Inizia verso Nord
|
|
||||||
|
|
||||||
for i in range(lunghezza_percorso):
|
|
||||||
var tipo = "dritto"
|
|
||||||
if i > 2: tipo = "curva" if randf() > 0.6 else "dritto"
|
|
||||||
|
|
||||||
if tipo == "dritto":
|
|
||||||
_piazza_dritto(pos_corrente, dir_corrente)
|
|
||||||
pos_corrente += dir_corrente
|
|
||||||
else:
|
|
||||||
var verso_destra = randf() > 0.5
|
|
||||||
var nuova_dir = Vector2i(-dir_corrente.y, dir_corrente.x) if verso_destra else Vector2i(dir_corrente.y, -dir_corrente.x)
|
|
||||||
|
|
||||||
# In un 3x3, la curva occupa:
|
|
||||||
# 1. Cella ingresso (dove siamo)
|
|
||||||
# 2. Cella centrale (pivot)
|
|
||||||
# 3. Cella uscita
|
|
||||||
var cella_ingresso = pos_corrente
|
|
||||||
var cella_centro = pos_corrente + dir_corrente
|
|
||||||
var cella_uscita = cella_centro + nuova_dir
|
|
||||||
|
|
||||||
_piazza_curva(cella_centro, dir_corrente, verso_destra)
|
|
||||||
|
|
||||||
# Occupiamo le celle nella mappa per il bioma
|
|
||||||
mappa_virtuale[cella_ingresso] = "binario"
|
|
||||||
mappa_virtuale[cella_centro] = "binario"
|
|
||||||
mappa_virtuale[cella_uscita] = "binario"
|
|
||||||
# Occupiamo anche l'angolo interno della L per sicurezza
|
|
||||||
mappa_virtuale[cella_ingresso + nuova_dir] = "binario"
|
|
||||||
|
|
||||||
# Il prossimo pezzo parte dopo l'uscita
|
|
||||||
pos_corrente = cella_uscita + nuova_dir
|
|
||||||
dir_corrente = nuova_dir
|
|
||||||
|
|
||||||
func _piazza_dritto(pos: Vector2i, dir: Vector2i) -> void:
|
|
||||||
var d = scena_dritto.instantiate()
|
|
||||||
add_child(d)
|
|
||||||
d.position = Vector3(pos.x * dimensione_chunk, 0, pos.y * dimensione_chunk)
|
|
||||||
d.rotation.y = _get_angolo_da_dir(dir)
|
|
||||||
mappa_virtuale[pos] = "binario"
|
|
||||||
_aggiungi_punti_path(d)
|
|
||||||
|
|
||||||
func _piazza_curva(pos_centro: Vector2i, dir_ingresso: Vector2i, destra: bool) -> void:
|
|
||||||
var c = scena_curva.instantiate()
|
|
||||||
add_child(c)
|
|
||||||
# Il pivot è al centro della 3x3, quindi lo piazziamo sulla cella centrale
|
|
||||||
c.position = Vector3(pos_centro.x * dimensione_chunk, 0, pos_centro.y * dimensione_chunk)
|
|
||||||
|
|
||||||
# Rotazione basata sulla direzione da cui entriamo
|
|
||||||
c.rotation.y = _get_angolo_da_dir(dir_ingresso)
|
|
||||||
|
|
||||||
if not destra:
|
|
||||||
c.scale.x = -1 # Specchia per curva a sinistra
|
|
||||||
# Se dopo lo specchio la curva guarda indietro, decommenta la riga sotto:
|
|
||||||
# c.rotate_y(deg_to_rad(180))
|
|
||||||
|
|
||||||
_aggiungi_punti_path(c)
|
|
||||||
|
|
||||||
func _get_angolo_da_dir(dir: Vector2i) -> float:
|
|
||||||
var ang = 0.0
|
|
||||||
if dir == Vector2i(0, -1): ang = 0.0 # Nord
|
|
||||||
elif dir == Vector2i(1, 0): ang = -PI/2.0 # Est
|
|
||||||
elif dir == Vector2i(0, 1): ang = PI # Sud
|
|
||||||
elif dir == Vector2i(-1, 0): ang = PI/2.0 # Ovest
|
|
||||||
return ang + deg_to_rad(OFFSET_ROTATION)
|
|
||||||
|
|
||||||
func _aggiungi_punti_path(chunk: Node3D) -> void:
|
|
||||||
if not path_treno: return
|
|
||||||
for i in range(1, 10):
|
|
||||||
var m = chunk.find_child("Punto_" + str(i), true, false)
|
|
||||||
if m:
|
|
||||||
path_treno.curve.add_point(path_treno.to_local(m.global_position))
|
|
||||||
else: break
|
|
||||||
|
|
||||||
# --- FASE 2: IL BIOMA (Onda BFS) ---
|
|
||||||
func _genera_bioma() -> void:
|
|
||||||
var coda = []
|
|
||||||
for p in mappa_virtuale.keys(): coda.append({"p": p, "d": 0})
|
|
||||||
|
|
||||||
while coda.size() > 0:
|
|
||||||
var curr = coda.pop_front()
|
|
||||||
if curr.d >= larghezza_bioma: continue
|
|
||||||
|
|
||||||
for off in [Vector2i(0,1), Vector2i(0,-1), Vector2i(1,0), Vector2i(-1,0)]:
|
|
||||||
var v = curr.p + off
|
|
||||||
if not mappa_virtuale.has(v):
|
|
||||||
_piazza_bioma(v)
|
|
||||||
coda.append({"p": v, "d": curr.d + 1})
|
|
||||||
|
|
||||||
func _piazza_bioma(pos: Vector2i) -> void:
|
|
||||||
var b = catalogo_bioma.pick_random().instantiate()
|
|
||||||
add_child(b)
|
|
||||||
b.position = Vector3(pos.x * dimensione_chunk, 0, pos.y * dimensione_chunk)
|
|
||||||
b.rotation.y = (randi() % 4) * (PI/2)
|
|
||||||
mappa_virtuale[pos] = "bioma"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://djnl28tvtgok0
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
extends PathFollow3D
|
|
||||||
|
|
||||||
@export var velocita_treno: float = 5.0
|
|
||||||
@export var in_movimento: bool = true
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if in_movimento:
|
|
||||||
# 'progress' è una variabile nativa di PathFollow3D
|
|
||||||
# Aumentandola, il nodo si sposta lungo la curva in automatico!
|
|
||||||
progress += velocita_treno * delta
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://bvn3yskdmvcuj
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
@tool
|
|
||||||
extends MultiMeshInstance3D
|
|
||||||
|
|
||||||
# Trascina qui la MeshInstance3D che rappresenta il volume della tua chioma
|
|
||||||
@export var mesh_volume: MeshInstance3D
|
|
||||||
|
|
||||||
# Clicca su questa casella nell'Inspector per generare le foglie
|
|
||||||
@export var genera_foglie: bool = false:
|
|
||||||
set(val):
|
|
||||||
if val:
|
|
||||||
popola_chioma()
|
|
||||||
genera_foglie = false # Resetta il pulsante
|
|
||||||
|
|
||||||
# Scala delle singole foglie
|
|
||||||
@export var scala_foglie: Vector3 = Vector3(1, 1, 1)
|
|
||||||
|
|
||||||
func popola_chioma():
|
|
||||||
if not mesh_volume or not mesh_volume.mesh:
|
|
||||||
print("Errore: Assegna una MeshInstance3D valida a 'Mesh Volume'.")
|
|
||||||
return
|
|
||||||
|
|
||||||
if not multimesh:
|
|
||||||
print("Errore: Il nodo MultiMeshInstance3D non ha una risorsa MultiMesh assegnata.")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Assicurati che il formato sia 3D per posizioni, rotazioni e scale
|
|
||||||
multimesh.transform_format = MultiMesh.TRANSFORM_3D
|
|
||||||
|
|
||||||
var mdt = MeshDataTool.new()
|
|
||||||
# Crea i dati dalla prima superficie della mesh (indice 0)
|
|
||||||
mdt.create_from_surface(mesh_volume.mesh, 0)
|
|
||||||
|
|
||||||
var numero_facce = mdt.get_face_count()
|
|
||||||
multimesh.instance_count = numero_facce
|
|
||||||
|
|
||||||
print("Generazione di ", numero_facce, " foglie...")
|
|
||||||
|
|
||||||
for i in range(numero_facce):
|
|
||||||
# Ottieni i tre vertici che formano la faccia
|
|
||||||
var v1 = mdt.get_vertex(mdt.get_face_vertex(i, 0))
|
|
||||||
var v2 = mdt.get_vertex(mdt.get_face_vertex(i, 1))
|
|
||||||
var v3 = mdt.get_vertex(mdt.get_face_vertex(i, 2))
|
|
||||||
|
|
||||||
# Calcola il centro della faccia
|
|
||||||
var centro_faccia = (v1 + v2 + v3) / 3.0
|
|
||||||
|
|
||||||
# Crea una trasformazione con posizione, rotazione casuale e scala
|
|
||||||
var transform = Transform3D()
|
|
||||||
transform.origin = centro_faccia
|
|
||||||
|
|
||||||
# Rotazione casuale per un look naturale
|
|
||||||
transform = transform.rotated(Vector3.UP, randf() * TAU) # Rotazione attorno all'asse Y
|
|
||||||
transform = transform.rotated(Vector3.RIGHT, randf() * TAU) # Rotazione attorno all'asse X
|
|
||||||
transform = transform.rotated(Vector3.FORWARD, randf() * TAU) # Rotazione attorno all'asse Z
|
|
||||||
|
|
||||||
# Applica la scala
|
|
||||||
transform = transform.scaled(scala_foglie)
|
|
||||||
|
|
||||||
# Imposta la trasformazione per questa istanza nel MultiMesh
|
|
||||||
multimesh.set_instance_transform(i, transform)
|
|
||||||
|
|
||||||
print("Foglie generate con successo!")
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://bj181l5u1b81x
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
shader_type canvas_item;
|
|
||||||
render_mode blend_mul;
|
|
||||||
|
|
||||||
// Colori esposti nell'Inspector
|
|
||||||
uniform vec4 color_mattina : source_color = vec4(1.0, 0.9, 0.8, 1.0);
|
|
||||||
uniform vec4 color_pomeriggio : source_color = vec4(1.0, 0.6, 0.2, 1.0);
|
|
||||||
uniform vec4 color_notte : source_color = vec4(0.1, 0.1, 0.3, 1.0);
|
|
||||||
|
|
||||||
// Parametro fluido: 1.0 = Mattina, 2.0 = Pomeriggio, 3.0 = Notte
|
|
||||||
uniform float tempo_giorno : hint_range(1.0, 3.0) = 1.0;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec4 tex_color = texture(TEXTURE, UV);
|
|
||||||
vec4 final_tint;
|
|
||||||
|
|
||||||
if (tempo_giorno <= 2.0) {
|
|
||||||
// Transizione tra Mattina (1.0) e Pomeriggio (2.0)
|
|
||||||
// mix(A, B, t) dove t va da 0 a 1
|
|
||||||
float t = tempo_giorno - 1.0;
|
|
||||||
final_tint = mix(color_mattina, color_pomeriggio, t);
|
|
||||||
} else {
|
|
||||||
// Transizione tra Pomeriggio (2.0) e Notte (3.0)
|
|
||||||
float t = tempo_giorno - 2.0;
|
|
||||||
final_tint = mix(color_pomeriggio, color_notte, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Applica il colore finale con blend_mul (moltiplicazione)
|
|
||||||
COLOR = tex_color * final_tint;
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://4n16lkrav6bj
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
shader_type spatial;
|
|
||||||
render_mode specular_disabled, ambient_light_disabled;
|
|
||||||
|
|
||||||
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap;
|
|
||||||
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_nearest;
|
|
||||||
uniform sampler2D NORMAL_TEXTURE : hint_normal_roughness_texture, filter_nearest;
|
|
||||||
|
|
||||||
uniform float lightIntensity = 1.25;
|
|
||||||
uniform float lineAlpha = 0.7;
|
|
||||||
uniform bool useLighting = true;
|
|
||||||
uniform float lineHighlight = 0.2;
|
|
||||||
uniform float lineShadow = 0.55;
|
|
||||||
|
|
||||||
varying vec2 screenUV;
|
|
||||||
varying float lineMask;
|
|
||||||
|
|
||||||
|
|
||||||
float GetLinearDepth(vec2 sUV, sampler2D depthTexture, mat4 invProjectionMat, float mask){
|
|
||||||
// Raw depth to linear depth code from:
|
|
||||||
// https://docs.godotengine.org/en/latest/tutorials/shaders/advanced_postprocessing.html
|
|
||||||
float depth = texture(depthTexture, sUV).x * mask;
|
|
||||||
vec3 ndc = vec3(sUV * 2.0 - 1.0, depth);
|
|
||||||
vec4 view = invProjectionMat * vec4(ndc, 1.0);
|
|
||||||
view.xyz /= view.w;
|
|
||||||
return -view.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 GetNormal(vec2 uv, sampler2D normalTexture, float mask){
|
|
||||||
vec3 normal = texture(normalTexture, uv).rgb;
|
|
||||||
normal = normal * 2.0 - 1.0 * mask;
|
|
||||||
return normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
float NormalEdgeIndicator(vec3 normalEdgeBias, vec3 normal, vec3 neighborNormal, float depthDifference){
|
|
||||||
//From Kody King: https://threejs.org/examples/webgl_postprocessing_pixel.html
|
|
||||||
float normalDifference = dot(normal - neighborNormal, normalEdgeBias);
|
|
||||||
float normalIndicator = clamp(smoothstep(-.01, .01, normalDifference), 0.0, 1.0);
|
|
||||||
float depthIndicator = clamp(sign(depthDifference * .25 + .0025), 0.0, 1.0);
|
|
||||||
return (1.0 - dot(normal, neighborNormal)) * depthIndicator * normalIndicator;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vertex(){
|
|
||||||
POSITION = vec4(VERTEX.xy, 1.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec2 texelSize = 1.0 / VIEWPORT_SIZE.xy;
|
|
||||||
screenUV = SCREEN_UV;
|
|
||||||
|
|
||||||
// UV offsets
|
|
||||||
vec2 UVOffsets[4];
|
|
||||||
UVOffsets[0] = SCREEN_UV + vec2(0.0, -1.0) * texelSize;
|
|
||||||
UVOffsets[1] = SCREEN_UV + vec2(0.0, 1.0) * texelSize;
|
|
||||||
UVOffsets[2] = SCREEN_UV + vec2(1.0, 0.0) * texelSize;
|
|
||||||
UVOffsets[3] = SCREEN_UV + vec2(-1.0, 0.0) * texelSize;
|
|
||||||
|
|
||||||
// Using alpha channel (screen roughness) to mask objects to not receive outlines
|
|
||||||
float outlineMask = texture(NORMAL_TEXTURE, SCREEN_UV).a;
|
|
||||||
outlineMask = ceil(outlineMask); // Objects with Roughness = 0 will not have and outline
|
|
||||||
|
|
||||||
// Edge detection with Depth
|
|
||||||
float depthDifference = 0.0;
|
|
||||||
float invDepthDifference = 0.5;
|
|
||||||
float depth = GetLinearDepth(SCREEN_UV, DEPTH_TEXTURE, INV_PROJECTION_MATRIX, outlineMask);
|
|
||||||
|
|
||||||
for (int i = 0; i < UVOffsets.length(); i++){
|
|
||||||
float dOff = GetLinearDepth(UVOffsets[i],DEPTH_TEXTURE, INV_PROJECTION_MATRIX, outlineMask);
|
|
||||||
depthDifference += clamp(dOff - depth, 0.0, 1.0);
|
|
||||||
invDepthDifference += depth - dOff;
|
|
||||||
}
|
|
||||||
invDepthDifference = clamp(invDepthDifference, 0.0, 1.0);
|
|
||||||
invDepthDifference = clamp(smoothstep(0.9, 0.9, invDepthDifference) * 10.0 , 0.0, 1.0);
|
|
||||||
depthDifference = smoothstep(0.25, 0.3, depthDifference);
|
|
||||||
|
|
||||||
// Edge detection with Normals
|
|
||||||
float normalDifference = 0.;
|
|
||||||
vec3 normalEdgeBias = vec3(1.0, 1.0, 1.0);
|
|
||||||
vec3 normal = GetNormal(SCREEN_UV, NORMAL_TEXTURE, outlineMask);
|
|
||||||
|
|
||||||
for (int i = 0; i < UVOffsets.length(); i++){
|
|
||||||
vec3 nOff = GetNormal(UVOffsets[i],NORMAL_TEXTURE, outlineMask);
|
|
||||||
normalDifference += NormalEdgeIndicator(normalEdgeBias, normal, nOff, depthDifference);
|
|
||||||
}
|
|
||||||
normalDifference = smoothstep(0.2, 0.2, normalDifference);
|
|
||||||
normalDifference = clamp(normalDifference - invDepthDifference, 0.0, 1.0);
|
|
||||||
|
|
||||||
|
|
||||||
ALBEDO = texture(SCREEN_TEXTURE, SCREEN_UV).rgb;
|
|
||||||
lineMask = clamp(0.1, lineAlpha, (depthDifference + normalDifference * 5.0));
|
|
||||||
|
|
||||||
|
|
||||||
if (!useLighting){
|
|
||||||
ALBEDO += clamp((normalDifference - depthDifference), 0.0, 1.0) * lineHighlight;
|
|
||||||
ALBEDO -= ALBEDO * depthDifference * lineShadow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void light (){
|
|
||||||
if (useLighting){
|
|
||||||
vec4 normal = texture(NORMAL_TEXTURE, screenUV);
|
|
||||||
normal = normal * 2.0 - 1.0;
|
|
||||||
|
|
||||||
// Calculate light direction
|
|
||||||
float dotNL = dot(normal.rgb, LIGHT);
|
|
||||||
dotNL = pow(dotNL, 2.5);
|
|
||||||
dotNL = clamp(dotNL, 0.0, 1.0);
|
|
||||||
|
|
||||||
if(LIGHT_IS_DIRECTIONAL)
|
|
||||||
DIFFUSE_LIGHT += mix(vec3(1.0), dotNL * LIGHT_COLOR * lightIntensity, lineMask);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DIFFUSE_LIGHT = vec3(1.0);
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://vfm72f8fcvup
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
shader_type spatial;
|
|
||||||
render_mode specular_disabled, ambient_light_disabled;
|
|
||||||
|
|
||||||
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap;
|
|
||||||
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_nearest;
|
|
||||||
uniform sampler2D NORMAL_TEXTURE : hint_normal_roughness_texture, filter_nearest;
|
|
||||||
|
|
||||||
uniform float lightIntensity = 1.25;
|
|
||||||
uniform float lineAlpha = 0.7;
|
|
||||||
uniform bool useLighting = true;
|
|
||||||
uniform float lineHighlight = 0.2;
|
|
||||||
uniform float lineShadow = 0.55;
|
|
||||||
|
|
||||||
varying vec2 screenUV;
|
|
||||||
varying float lineMask;
|
|
||||||
|
|
||||||
|
|
||||||
float GetLinearDepth(vec2 sUV, sampler2D depthTexture, mat4 invProjectionMat, float mask){
|
|
||||||
// Raw depth to linear depth code from:
|
|
||||||
// https://docs.godotengine.org/en/latest/tutorials/shaders/advanced_postprocessing.html
|
|
||||||
float depth = texture(depthTexture, sUV).x * mask;
|
|
||||||
vec3 ndc = vec3(sUV * 2.0 - 1.0, depth);
|
|
||||||
vec4 view = invProjectionMat * vec4(ndc, 1.0);
|
|
||||||
view.xyz /= view.w;
|
|
||||||
return -view.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 GetNormal(vec2 uv, sampler2D normalTexture, float mask){
|
|
||||||
vec3 normal = texture(normalTexture, uv).rgb;
|
|
||||||
normal = normal * 2.0 - 1.0 * mask;
|
|
||||||
return normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
float NormalEdgeIndicator(vec3 normalEdgeBias, vec3 normal, vec3 neighborNormal, float depthDifference){
|
|
||||||
//From Kody King: https://threejs.org/examples/webgl_postprocessing_pixel.html
|
|
||||||
float normalDifference = dot(normal - neighborNormal, normalEdgeBias);
|
|
||||||
float normalIndicator = clamp(smoothstep(-.01, .01, normalDifference), 0.0, 1.0);
|
|
||||||
float depthIndicator = clamp(sign(depthDifference * .25 + .0025), 0.0, 1.0);
|
|
||||||
return (1.0 - dot(normal, neighborNormal)) * depthIndicator * normalIndicator;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vertex(){
|
|
||||||
POSITION = vec4(VERTEX.xy, 1.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec2 texelSize = 1.0 / VIEWPORT_SIZE.xy;
|
|
||||||
screenUV = SCREEN_UV;
|
|
||||||
|
|
||||||
// UV offsets
|
|
||||||
vec2 UVOffsets[4];
|
|
||||||
UVOffsets[0] = SCREEN_UV + vec2(0.0, -1.0) * texelSize;
|
|
||||||
UVOffsets[1] = SCREEN_UV + vec2(0.0, 1.0) * texelSize;
|
|
||||||
UVOffsets[2] = SCREEN_UV + vec2(1.0, 0.0) * texelSize;
|
|
||||||
UVOffsets[3] = SCREEN_UV + vec2(-1.0, 0.0) * texelSize;
|
|
||||||
|
|
||||||
// Using alpha channel (screen roughness) to mask objects to not receive outlines
|
|
||||||
float outlineMask = texture(NORMAL_TEXTURE, SCREEN_UV).a;
|
|
||||||
outlineMask = ceil(outlineMask); // Objects with Roughness = 0 will not have and outline
|
|
||||||
|
|
||||||
// Edge detection with Depth
|
|
||||||
float depthDifference = 0.0;
|
|
||||||
float invDepthDifference = 0.5;
|
|
||||||
float depth = GetLinearDepth(SCREEN_UV, DEPTH_TEXTURE, INV_PROJECTION_MATRIX, outlineMask);
|
|
||||||
|
|
||||||
for (int i = 0; i < UVOffsets.length(); i++){
|
|
||||||
float dOff = GetLinearDepth(UVOffsets[i],DEPTH_TEXTURE, INV_PROJECTION_MATRIX, outlineMask);
|
|
||||||
depthDifference += clamp(dOff - depth, 0.0, 1.0);
|
|
||||||
invDepthDifference += depth - dOff;
|
|
||||||
}
|
|
||||||
invDepthDifference = clamp(invDepthDifference, 0.0, 1.0);
|
|
||||||
invDepthDifference = clamp(smoothstep(0.9, 0.9, invDepthDifference) * 10.0 , 0.0, 1.0);
|
|
||||||
depthDifference = smoothstep(0.25, 0.3, depthDifference);
|
|
||||||
|
|
||||||
// Edge detection with Normals
|
|
||||||
float normalDifference = 0.;
|
|
||||||
vec3 normalEdgeBias = vec3(1.0, 1.0, 1.0);
|
|
||||||
vec3 normal = GetNormal(SCREEN_UV, NORMAL_TEXTURE, outlineMask);
|
|
||||||
|
|
||||||
for (int i = 0; i < UVOffsets.length(); i++){
|
|
||||||
vec3 nOff = GetNormal(UVOffsets[i],NORMAL_TEXTURE, outlineMask);
|
|
||||||
normalDifference += NormalEdgeIndicator(normalEdgeBias, normal, nOff, depthDifference);
|
|
||||||
}
|
|
||||||
normalDifference = smoothstep(0.2, 0.2, normalDifference);
|
|
||||||
normalDifference = clamp(normalDifference - invDepthDifference, 0.0, 1.0);
|
|
||||||
|
|
||||||
|
|
||||||
ALBEDO = texture(SCREEN_TEXTURE, SCREEN_UV).rgb;
|
|
||||||
lineMask = clamp(0.1, lineAlpha, (depthDifference + normalDifference * 5.0));
|
|
||||||
|
|
||||||
|
|
||||||
if (!useLighting){
|
|
||||||
ALBEDO += clamp((normalDifference - depthDifference), 0.0, 1.0) * lineHighlight;
|
|
||||||
ALBEDO -= ALBEDO * depthDifference * lineShadow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void light (){
|
|
||||||
if (useLighting){
|
|
||||||
vec4 normal = texture(NORMAL_TEXTURE, screenUV);
|
|
||||||
normal = normal * 2.0 - 1.0;
|
|
||||||
|
|
||||||
// Calculate light direction
|
|
||||||
float dotNL = dot(normal.rgb, LIGHT);
|
|
||||||
dotNL = pow(dotNL, 2.5);
|
|
||||||
dotNL = clamp(dotNL, 0.0, 1.0);
|
|
||||||
|
|
||||||
if(LIGHT_IS_DIRECTIONAL)
|
|
||||||
DIFFUSE_LIGHT += mix(vec3(1.0), dotNL * LIGHT_COLOR * lightIntensity, lineMask);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DIFFUSE_LIGHT = vec3(1.0);
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://bj20y6cydpck6
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
shader_type spatial;
|
|
||||||
render_mode specular_disabled;
|
|
||||||
|
|
||||||
// --- TEXTURE E COLORE BASE ---
|
|
||||||
uniform sampler2D albedo_texture : source_color, filter_nearest_mipmap;
|
|
||||||
uniform vec4 color_tint : source_color = vec4(1.0);
|
|
||||||
|
|
||||||
// --- CORREZIONE IMMAGINE ---
|
|
||||||
uniform float saturation : hint_range(0.0, 2.0) = 1.0;
|
|
||||||
uniform float brightness : hint_range(0.0, 2.0) = 1.0;
|
|
||||||
|
|
||||||
// --- LUCE E OMBRA ---
|
|
||||||
uniform float light_steps = 4.0; // Gradini di luce
|
|
||||||
uniform float shadow_intensity : hint_range(0.0, 1.0) = 0.5; // Quanto è scura l'ombra (0=nera)
|
|
||||||
|
|
||||||
// *** NUOVO PARAMETRO ***
|
|
||||||
// Colore con cui tingere le ombre. Default: Grigio-Bluastro (Cool shadows)
|
|
||||||
uniform vec4 shadow_tint : source_color = vec4(0.6, 0.6, 0.7, 1.0);
|
|
||||||
|
|
||||||
void vertex() {
|
|
||||||
// Vuoto per prop statici
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec4 tex_color = texture(albedo_texture, UV);
|
|
||||||
vec3 base_rgb = tex_color.rgb * color_tint.rgb;
|
|
||||||
|
|
||||||
// --- SATURAZIONE ---
|
|
||||||
float luminance = dot(base_rgb, vec3(0.299, 0.587, 0.114));
|
|
||||||
vec3 saturated_color = mix(vec3(luminance), base_rgb, saturation);
|
|
||||||
|
|
||||||
// --- LUMINOSITA' ---
|
|
||||||
ALBEDO = saturated_color * brightness;
|
|
||||||
|
|
||||||
ROUGHNESS = 1.0;
|
|
||||||
SPECULAR = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void light() {
|
|
||||||
// --- CEL SHADING ---
|
|
||||||
float NdotL = dot(NORMAL, LIGHT);
|
|
||||||
float light_amount = clamp(NdotL, 0.0, 1.0);
|
|
||||||
|
|
||||||
// Gradini
|
|
||||||
light_amount = ceil(light_amount * light_steps) / light_steps;
|
|
||||||
|
|
||||||
// Ombre proiettate (attenuazione)
|
|
||||||
float shadow = ATTENUATION;
|
|
||||||
shadow = ceil(shadow * light_steps) / light_steps;
|
|
||||||
|
|
||||||
// Calcolo quanta luce totale riceve il pixel (0.0 = ombra totale, 1.0 = luce piena)
|
|
||||||
float final_light_factor = light_amount * shadow;
|
|
||||||
|
|
||||||
// --- IL TRUCCO DEL HUE SHIFT ---
|
|
||||||
// Invece di moltiplicare solo per la luce, facciamo un mix tra:
|
|
||||||
// A) Colore in Ombra (Albedo * Tinta Ombra * Intensità minima)
|
|
||||||
// B) Colore Illuminato (Albedo * Colore Luce)
|
|
||||||
|
|
||||||
vec3 lit_color = ALBEDO * LIGHT_COLOR;
|
|
||||||
vec3 shadowed_color = ALBEDO * shadow_tint.rgb * shadow_intensity; // L'ombra si colora!
|
|
||||||
|
|
||||||
// Mischiamo i due stati in base alla luce ricevuta
|
|
||||||
vec3 final_color = mix(shadowed_color, lit_color, final_light_factor);
|
|
||||||
|
|
||||||
DIFFUSE_LIGHT += final_color / PI;
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://c8b30c87lfclb
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
[gd_resource type="VisualShader" format=3 uid="uid://dktuskj3gem52"]
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_don5s"]
|
|
||||||
default_input_values = [0, Quaternion(0, 0, 0, 0), 1, Quaternion(0, 0, 0, 0)]
|
|
||||||
op_type = 2
|
|
||||||
operator = 2
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_rvu6f"]
|
|
||||||
default_input_values = [0, Quaternion(0, 0, 0, 0), 1, Quaternion(11133, 12, 12321211, 0)]
|
|
||||||
op_type = 2
|
|
||||||
operator = 5
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeVec4Constant" id="VisualShaderNodeVec4Constant_d4ljy"]
|
|
||||||
constant = Quaternion(1.25, 1.25, 1.25, 1.25)
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeFloatConstant" id="VisualShaderNodeFloatConstant_cc8xj"]
|
|
||||||
constant = 0.8
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeFloatConstant" id="VisualShaderNodeFloatConstant_lhbqr"]
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeColorParameter" id="VisualShaderNodeColorParameter_k2ihi"]
|
|
||||||
parameter_name = "sColorParameter"
|
|
||||||
default_value_enabled = true
|
|
||||||
default_value = Color(0, 0.26666668, 0.53333336, 1)
|
|
||||||
|
|
||||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_ttifq"]
|
|
||||||
noise_type = 0
|
|
||||||
fractal_type = 3
|
|
||||||
fractal_octaves = 10
|
|
||||||
fractal_lacunarity = 1.555
|
|
||||||
fractal_gain = 1.445
|
|
||||||
fractal_weighted_strength = 1.0
|
|
||||||
cellular_jitter = 0.0
|
|
||||||
|
|
||||||
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_6ruds"]
|
|
||||||
width = 1500
|
|
||||||
height = 1500
|
|
||||||
noise = SubResource("FastNoiseLite_ttifq")
|
|
||||||
seamless = true
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeTexture" id="VisualShaderNodeTexture_v5yg7"]
|
|
||||||
texture = SubResource("NoiseTexture2D_6ruds")
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeVectorOp" id="VisualShaderNodeVectorOp_mxguh"]
|
|
||||||
output_port_for_preview = 0
|
|
||||||
default_input_values = [0, Quaternion(0, 0, 0, 0), 1, Quaternion(0, 0, 0, 0)]
|
|
||||||
op_type = 2
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeUVFunc" id="VisualShaderNodeUVFunc_jmfs5"]
|
|
||||||
default_input_values = [1, Vector2(0.02, 0.02), 2, Vector2(0, 0)]
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_kiici"]
|
|
||||||
input_name = "time"
|
|
||||||
|
|
||||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_nj26y"]
|
|
||||||
noise_type = 2
|
|
||||||
seed = 1
|
|
||||||
fractal_type = 0
|
|
||||||
cellular_distance_function = 1
|
|
||||||
|
|
||||||
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_8egqe"]
|
|
||||||
width = 1500
|
|
||||||
height = 1500
|
|
||||||
noise = SubResource("FastNoiseLite_nj26y")
|
|
||||||
seamless = true
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeTexture" id="VisualShaderNodeTexture_x3kgx"]
|
|
||||||
texture = SubResource("NoiseTexture2D_8egqe")
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeUVFunc" id="VisualShaderNodeUVFunc_4sw7m"]
|
|
||||||
default_input_values = [1, Vector2(-0.02, -0.02), 2, Vector2(0, 0)]
|
|
||||||
|
|
||||||
[sub_resource type="VisualShaderNodeInput" id="VisualShaderNodeInput_itkh5"]
|
|
||||||
input_name = "time"
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
nodes/fragment/0/position = Vector2(680, 200)
|
|
||||||
nodes/fragment/2/node = SubResource("VisualShaderNodeColorParameter_k2ihi")
|
|
||||||
nodes/fragment/2/position = Vector2(-400, 80)
|
|
||||||
nodes/fragment/3/node = SubResource("VisualShaderNodeTexture_v5yg7")
|
|
||||||
nodes/fragment/3/position = Vector2(-640, 360)
|
|
||||||
nodes/fragment/4/node = SubResource("VisualShaderNodeVectorOp_mxguh")
|
|
||||||
nodes/fragment/4/position = Vector2(80, 140)
|
|
||||||
nodes/fragment/5/node = SubResource("VisualShaderNodeUVFunc_jmfs5")
|
|
||||||
nodes/fragment/5/position = Vector2(-920, 460)
|
|
||||||
nodes/fragment/6/node = SubResource("VisualShaderNodeInput_kiici")
|
|
||||||
nodes/fragment/6/position = Vector2(-1260, 560)
|
|
||||||
nodes/fragment/7/node = SubResource("VisualShaderNodeTexture_x3kgx")
|
|
||||||
nodes/fragment/7/position = Vector2(-640, 720)
|
|
||||||
nodes/fragment/8/node = SubResource("VisualShaderNodeUVFunc_4sw7m")
|
|
||||||
nodes/fragment/8/position = Vector2(-920, 780)
|
|
||||||
nodes/fragment/9/node = SubResource("VisualShaderNodeInput_itkh5")
|
|
||||||
nodes/fragment/9/position = Vector2(-1260, 880)
|
|
||||||
nodes/fragment/10/node = SubResource("VisualShaderNodeVectorOp_don5s")
|
|
||||||
nodes/fragment/10/position = Vector2(-420, 560)
|
|
||||||
nodes/fragment/11/node = SubResource("VisualShaderNodeVectorOp_rvu6f")
|
|
||||||
nodes/fragment/11/position = Vector2(-200, 560)
|
|
||||||
nodes/fragment/12/node = SubResource("VisualShaderNodeVec4Constant_d4ljy")
|
|
||||||
nodes/fragment/12/position = Vector2(-200, 740)
|
|
||||||
nodes/fragment/13/node = SubResource("VisualShaderNodeFloatConstant_cc8xj")
|
|
||||||
nodes/fragment/13/position = Vector2(440, 300)
|
|
||||||
nodes/fragment/14/node = SubResource("VisualShaderNodeFloatConstant_lhbqr")
|
|
||||||
nodes/fragment/14/position = Vector2(440, 400)
|
|
||||||
nodes/fragment/connections = PackedInt32Array(2, 0, 4, 0, 5, 0, 3, 0, 6, 0, 5, 2, 8, 0, 7, 0, 9, 0, 8, 2, 3, 0, 10, 0, 10, 0, 11, 0, 12, 0, 11, 1, 11, 0, 4, 1, 3, 0, 0, 0)
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
shader_type spatial;
|
|
||||||
render_mode specular_disabled;
|
|
||||||
|
|
||||||
|
|
||||||
uniform vec4 ground_color : source_color;
|
|
||||||
uniform float outline_mask = 1.0;
|
|
||||||
|
|
||||||
varying vec4 world_pos;
|
|
||||||
|
|
||||||
void vertex() {
|
|
||||||
world_pos = MODEL_MATRIX * vec4(VERTEX, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
ALBEDO = ground_color.rgb;
|
|
||||||
SPECULAR = 0.0;
|
|
||||||
ROUGHNESS = outline_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
void light() {
|
|
||||||
float light = clamp(dot(NORMAL, LIGHT), 0.0, 1.0);
|
|
||||||
DIFFUSE_LIGHT += light * (LIGHT_COLOR / PI) * ATTENUATION;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://bifltg3r6fjhh
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
shader_type spatial;
|
|
||||||
// Unshaded è essenziale per avere colori piatti e puliti
|
|
||||||
render_mode specular_disabled, cull_disabled, unshaded;
|
|
||||||
|
|
||||||
// --- GLOBAL UNIFORMS (Vento) ---
|
|
||||||
global uniform float wind_scale;
|
|
||||||
global uniform float wind_speed;
|
|
||||||
global uniform float wind_strength;
|
|
||||||
global uniform vec3 wind_direction;
|
|
||||||
global uniform sampler2D wind_noise : filter_linear_mipmap;
|
|
||||||
|
|
||||||
// --- PARAMETRI ESTETICI ---
|
|
||||||
uniform bool billboard_enabled = true; // <--- PULSANTE ON/OFF BILLBOARD
|
|
||||||
uniform bool wind_enabled = true; // <--- PULSANTE ON/OFF VENTO
|
|
||||||
uniform vec4 base_color : source_color = vec4(0.2, 0.6, 0.3, 1.0);
|
|
||||||
uniform sampler2D alpha_texture : source_color, filter_nearest;
|
|
||||||
uniform float leaves_scale = 1.0;
|
|
||||||
uniform float rotation_degrees = 0.0;
|
|
||||||
uniform vec2 texture_offset = vec2(0.0, 0.0);
|
|
||||||
|
|
||||||
// --- CONTROLLO GRADIENTE E RANDOM ---
|
|
||||||
uniform float height_min = 0.0;
|
|
||||||
uniform float height_max = 5.0;
|
|
||||||
uniform float shadow_intensity : hint_range(0.0, 1.0) = 0.5;
|
|
||||||
uniform float highlight_intensity : hint_range(0.0, 1.0) = 0.3;
|
|
||||||
uniform float light_steps : hint_range(1.0, 10.0) = 4.0;
|
|
||||||
uniform float random_mix : hint_range(0.0, 1.0) = 0.3;
|
|
||||||
|
|
||||||
varying vec3 v_final_color;
|
|
||||||
|
|
||||||
float hash(vec3 p) {
|
|
||||||
p = fract(p * 0.1031);
|
|
||||||
p += dot(p, p.yzx + 33.33);
|
|
||||||
return fract((p.x + p.y) * p.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
void vertex() {
|
|
||||||
vec3 instance_pos = MODEL_MATRIX[3].xyz;
|
|
||||||
|
|
||||||
// --- LOGICA VENTO ---
|
|
||||||
float total_angle = radians(rotation_degrees);
|
|
||||||
if (wind_enabled) {
|
|
||||||
float time = TIME * wind_speed;
|
|
||||||
vec2 noise_uv = (instance_pos.xz * wind_scale) + (time * wind_direction.xz * 0.5);
|
|
||||||
float noise_val = textureLod(wind_noise, noise_uv, 2.0).r;
|
|
||||||
float sway = sin(time + (noise_val * 10.0));
|
|
||||||
total_angle += (sway * wind_strength);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- CALCOLO COLORE ---
|
|
||||||
float h_factor = clamp((instance_pos.y - height_min) / (height_max - height_min), 0.0, 1.0);
|
|
||||||
float leaf_rand = hash(instance_pos);
|
|
||||||
float combined_factor = mix(h_factor, leaf_rand, random_mix);
|
|
||||||
combined_factor = ceil(combined_factor * light_steps) / light_steps;
|
|
||||||
|
|
||||||
vec3 dark_color = base_color.rgb * (1.0 - shadow_intensity);
|
|
||||||
vec3 light_color = base_color.rgb + (vec3(1.0) - base_color.rgb) * highlight_intensity;
|
|
||||||
v_final_color = mix(dark_color, light_color, combined_factor);
|
|
||||||
|
|
||||||
// --- LOGICA TRASFORMAZIONE (BILLBOARD vs STANDARD) ---
|
|
||||||
if (billboard_enabled) {
|
|
||||||
// Logica Billboard: guarda sempre la camera
|
|
||||||
vec3 view_pos_origin = (VIEW_MATRIX * vec4(instance_pos, 1.0)).xyz;
|
|
||||||
vec2 offset = (UV - 0.5) * leaves_scale;
|
|
||||||
|
|
||||||
float c = cos(total_angle);
|
|
||||||
float s = sin(total_angle);
|
|
||||||
vec2 rotated_offset = vec2(offset.x * c - offset.y * s, offset.x * s + offset.y * c);
|
|
||||||
|
|
||||||
vec3 final_pos = view_pos_origin + vec3(rotated_offset.x, rotated_offset.y, 0.0);
|
|
||||||
|
|
||||||
MODELVIEW_MATRIX = mat4(1.0);
|
|
||||||
MODELVIEW_MATRIX[3].xyz = final_pos;
|
|
||||||
VERTEX = vec3(0.0);
|
|
||||||
} else {
|
|
||||||
// Logica Standard: usa la rotazione e posizione della mesh
|
|
||||||
// Applichiamo comunque la rotazione extra e lo scale se desiderato
|
|
||||||
float c = cos(total_angle);
|
|
||||||
float s = sin(total_angle);
|
|
||||||
|
|
||||||
// Modifichiamo il vertice locale prima della trasformazione world
|
|
||||||
vec2 local_v = (VERTEX.xy) * leaves_scale;
|
|
||||||
VERTEX.x = local_v.x * c - local_v.y * s;
|
|
||||||
VERTEX.y = local_v.x * s + local_v.y * c;
|
|
||||||
// La MODELVIEW_MATRIX rimane quella di default fornita da Godot
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec2 shifted_uv = UV + texture_offset;
|
|
||||||
vec4 tex = texture(alpha_texture, shifted_uv);
|
|
||||||
|
|
||||||
ALBEDO = v_final_color;
|
|
||||||
ALPHA = tex.r;
|
|
||||||
ALPHA_SCISSOR_THRESHOLD = 0.5;
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://cvgukw0n6aw74
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
shader_type spatial;
|
|
||||||
render_mode unshaded;
|
|
||||||
|
|
||||||
group_uniforms Albedo_Settings;
|
|
||||||
uniform vec4 albedo_color : source_color = vec4(1.0);
|
|
||||||
uniform sampler2D albedo_texture : source_color, filter_nearest;
|
|
||||||
uniform bool use_texture = true;
|
|
||||||
uniform vec2 uv_scale = vec2(1.0, 1.0);
|
|
||||||
|
|
||||||
group_uniforms Toon_Lighting;
|
|
||||||
uniform vec3 light_direction = vec3(0.5, 1.0, 0.5);
|
|
||||||
uniform float light_steps : hint_range(1.0, 10.0, 1.0) = 3.0;
|
|
||||||
uniform float step_softness : hint_range(0.01, 1.0) = 0.1;
|
|
||||||
uniform vec4 shadow_color : source_color = vec4(0.4, 0.4, 0.6, 1.0);
|
|
||||||
uniform float shadow_offset : hint_range(-1.0, 1.0) = 0.0;
|
|
||||||
|
|
||||||
group_uniforms Emission_Settings;
|
|
||||||
uniform vec4 emission_color : source_color = vec4(0.0, 0.0, 0.0, 1.0); // Nero di default
|
|
||||||
uniform float emission_energy : hint_range(0.0, 16.0) = 0.0; // A 0 l'emissione è spenta
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
// 1. Albedo
|
|
||||||
vec4 tex = texture(albedo_texture, UV * uv_scale);
|
|
||||||
vec3 base_color = albedo_color.rgb;
|
|
||||||
if (use_texture) base_color *= tex.rgb;
|
|
||||||
|
|
||||||
// 2. Luce (World Space Fix)
|
|
||||||
vec3 world_light_dir = normalize(light_direction);
|
|
||||||
vec3 view_light_dir = (VIEW_MATRIX * vec4(world_light_dir, 0.0)).xyz;
|
|
||||||
float n_dot_l = dot(NORMAL, normalize(view_light_dir));
|
|
||||||
|
|
||||||
// 3. Toon Stepping
|
|
||||||
float intensity = clamp(n_dot_l + shadow_offset, 0.0, 1.0);
|
|
||||||
float raw_step = intensity * light_steps;
|
|
||||||
float lower_step = floor(raw_step);
|
|
||||||
float fract_step = fract(raw_step);
|
|
||||||
float lerp_step = smoothstep(0.5 - step_softness, 0.5 + step_softness, fract_step);
|
|
||||||
float stepped_intensity = (lower_step + lerp_step) / light_steps;
|
|
||||||
|
|
||||||
// 4. Mixing base
|
|
||||||
vec3 light_part = base_color * 1.2;
|
|
||||||
vec3 shaded_part = base_color * shadow_color.rgb;
|
|
||||||
vec3 final_rgb = mix(shaded_part, light_part, clamp(stepped_intensity, 0.0, 1.0));
|
|
||||||
|
|
||||||
ALBEDO = final_rgb;
|
|
||||||
|
|
||||||
// 5. Emission
|
|
||||||
// Moltiplica il colore per l'energia impostata dall'utente
|
|
||||||
EMISSION = emission_color.rgb * emission_energy;
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://n2fjgynfljhx
|
|
||||||
Reference in New Issue
Block a user