148 lines
6.0 KiB
Plaintext
148 lines
6.0 KiB
Plaintext
shader_type spatial;
|
|
|
|
render_mode diffuse_toon, specular_disabled, ambient_light_disabled;
|
|
|
|
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);
|
|
uniform float palette_shift_y : hint_range(0.0, 1.0) = 0.0;
|
|
|
|
group_uniforms Height_Gradient;
|
|
global uniform vec4 global_gradient_color_top;
|
|
global uniform vec4 global_gradient_color_bot;
|
|
global uniform float global_gradient_intensity;
|
|
uniform float gradient_start_y = 0.0;
|
|
uniform float gradient_end_y = 10.0;
|
|
|
|
group_uniforms Top_Down_Local_Gradient;
|
|
uniform bool use_local_gradient = true;
|
|
uniform vec4 local_gradient_color_top : source_color = vec4(1.0, 1.0, 1.0, 1.0);
|
|
uniform vec4 local_gradient_color_bot : source_color = vec4(0.15, 0.15, 0.25, 1.0);
|
|
uniform float local_gradient_start = -1.0;
|
|
uniform float local_gradient_end = 1.0;
|
|
uniform float local_gradient_intensity : hint_range(0.0, 1.0) = 0.5;
|
|
|
|
// CONTROLLI DI ROTAZIONE
|
|
uniform float rotazione_gradiente_x : hint_range(-180.0, 180.0) = 0.0;
|
|
uniform float rotazione_gradiente_y : hint_range(-180.0, 180.0) = 0.0;
|
|
uniform float rotazione_gradiente_z : hint_range(-180.0, 180.0) = 0.0;
|
|
|
|
// NUOVI CONTROLLI PER IL FRASTAGLIATO (LOOK GHIBLI)
|
|
uniform float local_gradient_jaggedness : hint_range(0.0, 2.0) = 0.3; // Ampiezza delle onde/pennellate
|
|
uniform float local_gradient_frequency : hint_range(0.1, 30.0) = 8.0; // Fittezza del frastagliato
|
|
|
|
group_uniforms Toon_Lighting;
|
|
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;
|
|
|
|
group_uniforms Ghibli_Directional_Glint;
|
|
uniform bool use_ghibli_glint = true;
|
|
uniform vec4 glint_color : source_color = vec4(1.0, 0.95, 0.85, 1.0);
|
|
uniform float glint_intensity : hint_range(0.0, 10.0) = 1.0;
|
|
uniform float glint_sharpness : hint_range(1.0, 128.0) = 32.0;
|
|
|
|
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;
|
|
|
|
varying float world_y;
|
|
varying vec3 local_pos_ruotata; // Passiamo l'intero vettore 3D ruotato al fragment
|
|
|
|
void vertex() {
|
|
world_y = (MODEL_MATRIX * vec4(VERTEX, 1.0)).y;
|
|
|
|
vec3 v_rotato = VERTEX;
|
|
|
|
float rad_x = radians(rotazione_gradiente_x);
|
|
float rad_y = radians(rotazione_gradiente_y);
|
|
float rad_z = radians(rotazione_gradiente_z);
|
|
|
|
// Rotazione Asse Y
|
|
float cy = cos(rad_y), sy = sin(rad_y);
|
|
float x1 = v_rotato.x * cy + v_rotato.z * sy;
|
|
float z1 = -v_rotato.x * sy + v_rotato.z * cy;
|
|
v_rotato.x = x1; v_rotato.z = z1;
|
|
|
|
// Rotazione Asse X
|
|
float cx = cos(rad_x), sx = sin(rad_x);
|
|
float y2 = v_rotato.y * cx - v_rotato.z * sx;
|
|
float z2 = v_rotato.y * sx + v_rotato.z * cx;
|
|
v_rotato.y = y2; v_rotato.z = z2;
|
|
|
|
// Rotazione Asse Z
|
|
float cz = cos(rad_z), sz = sin(rad_z);
|
|
float x3 = v_rotato.x * cz - v_rotato.y * sz;
|
|
float y3 = v_rotato.x * sz + v_rotato.y * cz;
|
|
v_rotato.x = x3; v_rotato.y = y3;
|
|
|
|
// Salviamo la posizione 3D trasformata
|
|
local_pos_ruotata = v_rotato;
|
|
}
|
|
|
|
void fragment() {
|
|
vec2 final_uv = (UV * uv_scale) + vec2(0.0, palette_shift_y);
|
|
vec4 tex = texture(albedo_texture, final_uv);
|
|
|
|
vec3 base_color = albedo_color.rgb;
|
|
if (use_texture) base_color *= tex.rgb;
|
|
|
|
// 1. Gradiente del Mondo
|
|
float grad_factor = smoothstep(gradient_start_y, gradient_end_y, world_y);
|
|
vec3 current_gradient_color = mix(global_gradient_color_bot.rgb, global_gradient_color_top.rgb, grad_factor);
|
|
base_color = mix(base_color, current_gradient_color, global_gradient_intensity);
|
|
|
|
// 2. Gradiente Locale Ruotabile e Frastagliato
|
|
if (use_local_gradient) {
|
|
// Generiamo un rumore stratificato stile "pennellata anime" unendo più onde sfasate
|
|
float freq = local_gradient_frequency;
|
|
float noise = sin(local_pos_ruotata.x * freq) * cos(local_pos_ruotata.z * freq);
|
|
// Secondo strato ad alta frequenza per rompere la simmetria matematica delle onde
|
|
noise += sin(local_pos_ruotata.z * freq * 2.13) * sin(local_pos_ruotata.y * freq * 1.77) * 0.5;
|
|
|
|
// Perturbiamo l'altezza locale effettiva usando il rumore calcolato
|
|
float local_y_frastagliata = local_pos_ruotata.y + (noise * local_gradient_jaggedness);
|
|
|
|
// Calcoliamo il fattore di gradiente sulla coordinata alterata
|
|
float local_grad_factor = smoothstep(local_gradient_start, local_gradient_end, local_y_frastagliata);
|
|
vec3 local_grad_color = mix(local_gradient_color_bot.rgb, local_gradient_color_top.rgb, local_grad_factor);
|
|
base_color = mix(base_color, local_grad_color, local_gradient_intensity);
|
|
}
|
|
|
|
ALBEDO = base_color;
|
|
EMISSION = emission_color.rgb * emission_energy;
|
|
}
|
|
|
|
void light() {
|
|
float shadow_factor = mix(1.0 - cast_shadow_strength, 1.0, ATTENUATION);
|
|
float cutoff_mask = smoothstep(0.0, 0.1, ATTENUATION);
|
|
|
|
float n_dot_l = dot(NORMAL, LIGHT);
|
|
|
|
// dither
|
|
float dither = fract(sin(dot(FRAGCOORD.xy, vec2(12.9898, 78.233))) * 43758.5453);
|
|
float intensity = (clamp(n_dot_l, 0.0, 1.0) * shadow_factor) + (dither - 0.5) * 0.02;
|
|
|
|
float raw_step = (intensity + shadow_offset) * light_steps;
|
|
float lower_step = floor(raw_step);
|
|
float fract_step = fract(raw_step);
|
|
float soft_lerp = smoothstep(0.5 - step_softness, 0.5 + step_softness, fract_step);
|
|
float stepped_intensity = (lower_step + soft_lerp) / light_steps;
|
|
|
|
// Toon colors
|
|
vec3 light_color_final = mix(shadow_color.rgb, vec3(1.1), clamp(stepped_intensity, 0.0, 1.0));
|
|
DIFFUSE_LIGHT += (light_color_final * LIGHT_COLOR) * cutoff_mask;
|
|
|
|
if (use_ghibli_glint) {
|
|
float glint_raw = pow(max(0.0, n_dot_l), glint_sharpness);
|
|
float glint_mask = smoothstep(0.5 - step_softness*0.5, 0.5 + step_softness*0.5, glint_raw);
|
|
glint_mask *= smoothstep(0.0, 0.1, n_dot_l);
|
|
vec3 extra_sun_glint = glint_mask * glint_color.rgb * LIGHT_COLOR * glint_intensity * ATTENUATION;
|
|
|
|
DIFFUSE_LIGHT += extra_sun_glint;
|
|
}
|
|
} |