add cloud shadow - godrays
This commit is contained in:
113
Shaders/Edge_detector.gdshader
Normal file
113
Shaders/Edge_detector.gdshader
Normal file
@@ -0,0 +1,113 @@
|
||||
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
Shaders/Edge_detector.gdshader.uid
Normal file
1
Shaders/Edge_detector.gdshader.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bj20y6cydpck6
|
||||
81
Shaders/Shadow_postProcess.gdshader
Normal file
81
Shaders/Shadow_postProcess.gdshader
Normal file
@@ -0,0 +1,81 @@
|
||||
shader_type spatial;
|
||||
|
||||
render_mode unshaded, depth_test_disabled, cull_disabled;
|
||||
|
||||
uniform sampler2D depth_texture : hint_depth_texture, repeat_disable, filter_nearest;
|
||||
uniform sampler2D noise_texture : repeat_enable, filter_linear;
|
||||
|
||||
uniform float cloud_scale : hint_range(0.001, 0.2) = 0.05;
|
||||
uniform float cloud_speed : hint_range(0.0, 1.0) = 0.05;
|
||||
uniform vec2 direction = vec2(1.0, 0.2);
|
||||
uniform vec2 sun_angle = vec2(0.5, 0.5);
|
||||
|
||||
group_uniforms Forma_Nuvola;
|
||||
uniform float cloud_density : hint_range(0.0, 1.0) = 0.5;
|
||||
uniform float center_sharpness : hint_range(0.0, 0.99) = 0.7;
|
||||
|
||||
group_uniforms Estetica;
|
||||
uniform vec3 shadow_color : source_color = vec3(0.0, 0.0, 0.0);
|
||||
uniform float opacity_center : hint_range(0.0, 1.0) = 0.5;
|
||||
uniform float opacity_edge : hint_range(0.0, 1.0) = 0.2;
|
||||
|
||||
group_uniforms Distanza_Sfumo;
|
||||
// Sfumo basato sulla distanza dalla telecamera (Profondità)
|
||||
uniform float fade_start : hint_range(10.0, 1000.0) = 150.0;
|
||||
uniform float fade_end : hint_range(50.0, 2000.0) = 300.0;
|
||||
|
||||
group_uniforms Altezza_Sfumo;
|
||||
// Sfumo basato sull'altezza dal suolo (Asse Y)
|
||||
uniform float height_fade_start : hint_range(0.0, 500.0) = 10.0; // Inizia a svanire sopra i 10 metri
|
||||
uniform float height_fade_end : hint_range(0.0, 1000.0) = 50.0; // Scompare del tutto a 50 metri di altezza
|
||||
|
||||
void vertex() {
|
||||
POSITION = vec4(VERTEX.xy, 1.0, 1.0);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
float depth = texture(depth_texture, SCREEN_UV).x;
|
||||
|
||||
if (depth >= 0.9999) {
|
||||
ALPHA = 0.0;
|
||||
} else {
|
||||
vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth);
|
||||
vec4 view_pos = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
|
||||
view_pos /= view_pos.w;
|
||||
// world_pos.y è l'altezza assoluta di questo pixel nel mondo 3D!
|
||||
vec4 world_pos = INV_VIEW_MATRIX * view_pos;
|
||||
|
||||
// 1. Sfumo di Distanza
|
||||
float dist = length(view_pos.xyz);
|
||||
float dist_fade = smoothstep(fade_end, fade_start, dist);
|
||||
|
||||
// 2. Sfumo di Altezza (LA NOVITÀ)
|
||||
// Se world_pos.y supera height_fade_start inizia a svanire. A height_fade_end è zero.
|
||||
float height_fade = smoothstep(height_fade_end, height_fade_start, world_pos.y);
|
||||
|
||||
// Moltiplichiamo i due sfumi. Se uno dei due dice "zero", l'ombra sparisce.
|
||||
float final_fade = dist_fade * height_fade;
|
||||
|
||||
if (final_fade <= 0.001) {
|
||||
ALPHA = 0.0;
|
||||
} else {
|
||||
vec2 projected_xz = world_pos.xz + (world_pos.y * sun_angle);
|
||||
vec2 uv = projected_xz * cloud_scale;
|
||||
uv += TIME * cloud_speed * vec2(-direction.x, direction.y);
|
||||
|
||||
float n = texture(noise_texture, uv).r;
|
||||
|
||||
if (n < (1.0 - cloud_density)) {
|
||||
ALPHA = 0.0;
|
||||
} else {
|
||||
float internal_n = (n - (1.0 - cloud_density)) / cloud_density;
|
||||
float is_center = step(center_sharpness, internal_n);
|
||||
|
||||
ALBEDO = shadow_color;
|
||||
|
||||
// Applichiamo il colore e lo sbiadiamo in base a distanza e altezza!
|
||||
ALPHA = mix(opacity_edge, opacity_center, is_center) * final_fade;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
Shaders/Shadow_postProcess.gdshader.uid
Normal file
1
Shaders/Shadow_postProcess.gdshader.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c0gopfoe0ij8g
|
||||
62
Shaders/godrays.gdshader
Normal file
62
Shaders/godrays.gdshader
Normal file
@@ -0,0 +1,62 @@
|
||||
shader_type spatial;
|
||||
|
||||
// RENDER MODE ESSENZIALI PER EFFETTI LUCE
|
||||
// blend_add: Somma i colori, perfetto per la luce pura.
|
||||
// unshaded: Non riceve ombre, è lui che illumina.
|
||||
// depth_draw_never: Non blocca gli oggetti dietro, evita artefatti.
|
||||
// cull_disabled: Visibile da entrambi i lati.
|
||||
render_mode blend_add, depth_draw_never, cull_disabled, unshaded;
|
||||
|
||||
uniform sampler2D depth_texture : hint_depth_texture, filter_nearest;
|
||||
uniform sampler2D noise_texture : repeat_enable, filter_linear;
|
||||
|
||||
uniform vec3 ray_color : source_color = vec3(1.0, 0.9, 0.7);
|
||||
uniform float base_alpha : hint_range(0.0, 1.0) = 0.5;
|
||||
|
||||
group_uniforms Noise_Stirato;
|
||||
// --- I PARAMETRI CHE CERCAVI ---
|
||||
uniform float noise_stretching : hint_range(1.0, 50.0) = 20.0; // Quanto allungare il noise
|
||||
uniform float noise_scale : hint_range(0.1, 10.0) = 1.0; // Grandezza generale
|
||||
uniform vec2 scrolling_speed = vec2(0.0, -0.1); // Velocità e direzione del movimento (Y negativa va in giù)
|
||||
|
||||
group_uniforms Fades;
|
||||
uniform float depth_softness = 1.0; // Ammorbidisce il contatto con terreno/alberi
|
||||
uniform float edge_fade_power = 2.0; // Sfuma i bordi laterali del piano
|
||||
|
||||
// --- IL PARAMETRO PER LO SCRIPT ---
|
||||
uniform float intensity_multiplier : hint_range(0.0, 1.0) = 0.0;
|
||||
|
||||
void fragment() {
|
||||
// 1. LA MAGIA DEL NOISE STIRATO E IN MOVIMENTO
|
||||
// Prendiamo le coordinate UV standard
|
||||
vec2 stretchy_uv = UV * noise_scale;
|
||||
|
||||
// STIRAMENTO: Moltiplichiamo X per allungare il noise in verticale
|
||||
stretchy_uv.x *= noise_stretching;
|
||||
|
||||
// MOVIMENTO: Aggiungiamo il tempo moltiplicato per la velocità
|
||||
stretchy_uv += TIME * scrolling_speed;
|
||||
|
||||
// Leggiamo il noise (basta un canale perché è in bianco e nero)
|
||||
float noise = texture(noise_texture, stretchy_uv).r;
|
||||
|
||||
// 2. SISTEMA DI DISSOLVENZE (FADES) PER NASCONDERE IL PIANO
|
||||
// A. Soft Intersection: Legge la profondità per sfumare il contatto con gli oggetti
|
||||
float depth = textureLod(depth_texture, SCREEN_UV, 0.0).r;
|
||||
vec4 upos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, depth, 1.0);
|
||||
vec3 pixel_position = upos.xyz / upos.w;
|
||||
float depth_fade = clamp((VERTEX.z - pixel_position.z) / depth_softness, 0.0, 1.0);
|
||||
|
||||
// B. Edge Fade: Sfuma orizzontalmente (UV.x) per non avere bordi netti ai lati del piano
|
||||
float edge_fade = smoothstep(0.0, 0.5, UV.x) * smoothstep(1.0, 0.5, UV.x);
|
||||
edge_fade = pow(edge_fade, edge_fade_power); // Rende la sfumatura più o meno aggressiva
|
||||
|
||||
// C. Vertical Fade: Sfuma verticalmente (UV.y) per far sparire la base nel nulla
|
||||
float vertical_fade = smoothstep(0.0, 0.2, UV.y) * smoothstep(1.0, 0.7, UV.y);
|
||||
|
||||
// 3. COMPOSIZIONE FINALE
|
||||
ALBEDO = ray_color;
|
||||
|
||||
// Combiniamo tutte le sfumature con il noise e il moltiplicatore dello script
|
||||
ALPHA = noise * base_alpha * depth_fade * edge_fade * vertical_fade * intensity_multiplier;
|
||||
}
|
||||
1
Shaders/godrays.gdshader.uid
Normal file
1
Shaders/godrays.gdshader.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dkmdtejrbks8n
|
||||
@@ -100,6 +100,8 @@ void fragment() {
|
||||
// Moltiplichiamo l'alpha della texture per il nuovo parametro opacity
|
||||
ALPHA = tex.r * opacity;
|
||||
ALPHA_SCISSOR_THRESHOLD = 0.5;
|
||||
|
||||
ROUGHNESS = 0.02;
|
||||
}
|
||||
|
||||
// --- NUOVA LOGICA LUCE (Ombre Proiettate e Fix Quadrati) ---
|
||||
|
||||
Reference in New Issue
Block a user