add fake shadow
This commit is contained in:
@@ -1,21 +1,35 @@
|
||||
shader_type spatial;
|
||||
|
||||
// Rimosso 'unshaded' per ricevere le ombre.
|
||||
// Aggiunto 'ambient_light_disabled' per proteggere la tua palette dai riflessi del cielo.
|
||||
render_mode specular_disabled, cull_disabled, ambient_light_disabled;
|
||||
|
||||
// --- GLOBAL UNIFORMS (Vento) ---
|
||||
// --- GLOBAL UNIFORMS (Vento e Neve) ---
|
||||
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;
|
||||
global uniform float global_snow_amount;
|
||||
|
||||
// --- PARAMETRI ESTETICI ---
|
||||
uniform bool billboard_enabled = true;
|
||||
uniform bool wind_enabled = true;
|
||||
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);
|
||||
uniform float opacity : hint_range(0.0, 1.0) = 1.0;
|
||||
|
||||
// --- PARAMETRI CHIAZZE ERBA (NOISE PATCHES) ---
|
||||
// Inserisci qui una texture Noise (es. FastNoiseLite in Godot)
|
||||
uniform sampler2D grass_noise : hint_default_white, filter_linear_mipmap;
|
||||
uniform float noise_scale = 0.05; // Più è basso, più le chiazze sono grandi
|
||||
uniform vec4 patch_color : source_color = vec4(0.1, 0.35, 0.2, 1.0); // Colore scuro della chiazza
|
||||
uniform float patch_threshold : hint_range(0.0, 1.0) = 0.5; // Regola quanto sono estese le chiazze
|
||||
uniform float patch_smoothness : hint_range(0.01, 1.0) = 0.2; // Morbidezza sfumatura ai bordi
|
||||
uniform float patch_intensity : hint_range(0.0, 1.0) = 0.85; // Quanto è forte il colore della chiazza
|
||||
|
||||
uniform vec4 snow_color : source_color = vec4(0.85, 0.9, 0.95, 1.0);
|
||||
|
||||
// --- CONTROLLO GRADIENTE E RANDOM ---
|
||||
uniform float height_min = 0.0;
|
||||
@@ -25,12 +39,11 @@ 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;
|
||||
|
||||
// NUOVO: Regola quanto è scura l'ombra proiettata (es. dal tronco) sull'erba
|
||||
uniform float cast_shadow_strength : hint_range(0.0, 1.0) = 0.6;
|
||||
|
||||
varying vec3 v_final_color;
|
||||
varying float v_shade_factor;
|
||||
|
||||
// Funzione hash per generare casualità basata sulla posizione
|
||||
float hash(vec3 p) {
|
||||
p = fract(p * 0.1031);
|
||||
p += dot(p, p.yzx + 33.33);
|
||||
@@ -38,62 +51,92 @@ float hash(vec3 p) {
|
||||
}
|
||||
|
||||
void vertex() {
|
||||
// 1. POSIZIONE DELL'ISTANZA
|
||||
vec3 instance_pos = MODEL_MATRIX[3].xyz;
|
||||
|
||||
// --- 2. LOGICA VENTO ---
|
||||
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));
|
||||
float total_angle = radians(rotation_degrees) + (sway * wind_strength);
|
||||
// --- 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);
|
||||
}
|
||||
|
||||
// --- 3. CALCOLO COLORE (LOGICA MIXATA) ---
|
||||
// --- CALCOLO COLORE BASE ---
|
||||
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;
|
||||
|
||||
v_shade_factor = combined_factor;
|
||||
|
||||
vec3 dark_color = base_color.rgb * (1.0 - shadow_intensity);
|
||||
vec3 light_color = base_color.rgb + (vec3(1.0) - base_color.rgb) * highlight_intensity;
|
||||
vec3 base_grass_color = mix(dark_color, light_color, combined_factor);
|
||||
|
||||
// ---> LOGICA CHIAZZE ERBA (NOISE) <---
|
||||
// Campioniamo il noise usando la posizione XZ del singolo ciuffo d'erba nel mondo.
|
||||
// Usiamo textureLod con 0.0 perché siamo nel vertex shader.
|
||||
float n_val = textureLod(grass_noise, instance_pos.xz * noise_scale, 0.0).r;
|
||||
|
||||
v_final_color = mix(dark_color, light_color, combined_factor);
|
||||
|
||||
// --- 4. LOGICA BILLBOARD ---
|
||||
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);
|
||||
// Creiamo la maschera per la chiazza: liscia ai bordi, solida al centro.
|
||||
float patch_mask = smoothstep(patch_threshold - patch_smoothness, patch_threshold + patch_smoothness, n_val);
|
||||
|
||||
vec3 final_pos = view_pos_origin + vec3(rotated_offset.x, rotated_offset.y, 0.0);
|
||||
// Mescoliamo il colore base dell'erba con il colore scuro della chiazza
|
||||
v_final_color = mix(base_grass_color, patch_color.rgb, patch_mask * patch_intensity);
|
||||
|
||||
MODELVIEW_MATRIX = mat4(1.0);
|
||||
MODELVIEW_MATRIX[3].xyz = final_pos;
|
||||
VERTEX = vec3(0.0);
|
||||
// --- LOGICA TRASFORMAZIONE ---
|
||||
if (billboard_enabled) {
|
||||
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 {
|
||||
float c = cos(total_angle);
|
||||
float s = sin(total_angle);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec4 tex = texture(alpha_texture, UV);
|
||||
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;
|
||||
// Trucco utile per non renderizzare i bordi trasparenti dei piani (opzionale)
|
||||
if (tex.r * opacity < 0.5) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// --- IL TRUCCO MAGICO PER L'EDGE DETECTOR ---
|
||||
// Impostiamo la roughness esattamente al 2%.
|
||||
// Il Compute Shader leggerà questo valore e non disegnerà i bordi neri qui sopra!
|
||||
ROUGHNESS = 0.02;
|
||||
float top_mask = 1.0 - shifted_uv.y;
|
||||
float snow_mask = smoothstep(1.0 - global_snow_amount, 1.2 - global_snow_amount, top_mask);
|
||||
snow_mask *= step(0.01, global_snow_amount);
|
||||
|
||||
vec3 dark_snow = snow_color.rgb * (1.0 - shadow_intensity);
|
||||
vec3 shaded_snow = mix(dark_snow, snow_color.rgb, v_shade_factor);
|
||||
|
||||
vec3 final_albedo = mix(v_final_color, shaded_snow, snow_mask);
|
||||
|
||||
ALBEDO = final_albedo;
|
||||
// ALPHA = tex.r * opacity; -> Disabilitato se usi 'discard' sopra.
|
||||
// ALPHA_SCISSOR_THRESHOLD = 0.5; -> Idem
|
||||
|
||||
ROUGHNESS = 0.02;
|
||||
}
|
||||
|
||||
// NUOVO: Calcolo luce custom che simula l'effetto "unshaded" (e ora fixa i quadrati!)
|
||||
void light() {
|
||||
float shadow_factor = mix(1.0 - cast_shadow_strength, 1.0, ATTENUATION);
|
||||
|
||||
// Maschera morbida per nascondere i quadrati
|
||||
float cutoff_mask = smoothstep(0.0, 0.05, ATTENUATION);
|
||||
|
||||
DIFFUSE_LIGHT += (shadow_factor * LIGHT_COLOR) * cutoff_mask;
|
||||
}
|
||||
@@ -25,9 +25,13 @@ 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;
|
||||
|
||||
uniform float cast_shadow_strength : hint_range(0.0, 1.0) = 0.6;
|
||||
|
||||
// ---> NUOVI PARAMETRI TOON SPECULAR <---
|
||||
uniform float specular_size : hint_range(10.0, 200.0) = 60.0; // Più è alto, più il punto luce è piccolo
|
||||
uniform float specular_softness : hint_range(0.0, 0.1) = 0.01; // Morbidezza del bordo del punto luce
|
||||
uniform float specular_intensity_multiplier : hint_range(0.0, 2.0) = 0.5; // Forza del riflesso
|
||||
|
||||
group_uniforms Emission_Settings;
|
||||
uniform vec4 emission_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
uniform float emission_energy : hint_range(0.0, 16.0) = 0.0;
|
||||
@@ -79,4 +83,22 @@ void light() {
|
||||
float cutoff_mask = smoothstep(0.0, 0.05, ATTENUATION);
|
||||
|
||||
DIFFUSE_LIGHT += (final_toon_light * LIGHT_COLOR) * cutoff_mask;
|
||||
|
||||
// ---> AGGIUNTA TOON SPECULAR (Metodo 1) <---
|
||||
// Calcoliamo la direzione a metà strada tra la vista e la luce
|
||||
vec3 half_direction = normalize(VIEW + LIGHT);
|
||||
float n_dot_h = max(0.0, dot(NORMAL, half_direction));
|
||||
|
||||
// Applichiamo la potenza (shininess) per definire la dimensione del punto luce
|
||||
float spec_power = pow(n_dot_h, specular_size);
|
||||
|
||||
// Creiamo un gradino netto (Toon) invece della sfumatura classica PBR
|
||||
float toon_specular = smoothstep(0.5 - specular_softness, 0.5 + specular_softness, spec_power);
|
||||
|
||||
// Moltiplichiamo il riflesso per il colore della luce (Sole o Luna)
|
||||
vec3 specular_highlight = LIGHT_COLOR * toon_specular * specular_intensity_multiplier;
|
||||
|
||||
// Sommiamo il punto luce finale alla diffusione, mascherandolo con "cutoff_mask"
|
||||
// per evitare che il riflesso brilli anche nelle zone in ombra profonda.
|
||||
DIFFUSE_LIGHT += (specular_highlight * cutoff_mask);
|
||||
}
|
||||
Reference in New Issue
Block a user