#ifdef GL_ES precision mediump float; #endif uniform float u_Time; uniform sampler2D u_Tex0; // Escena del juego uniform sampler2D u_Tex1; // Textura rain.png varying vec2 v_TexCoord; uniform vec2 u_WalkOffset; uniform float u_Floor; void main(void) { // 1. Restricción de piso (solo superficie y arriba) if (u_Floor > 7.0) discard; // 2. Coordenadas de la escena vec4 Game = texture2D(u_Tex0, v_TexCoord); // 3. Coordenadas para la lluvia (Screen Space + Movimiento) // Usamos gl_FragCoord para que sea independiente de los tiles del mapa. vec2 screenUV = gl_FragCoord.xy / 512.0; // u_WalkOffset normalizado para fluidez al caminar vec2 smoothWalk = u_WalkOffset / 32.0; // Desplazamiento de la textura para caída a 135º (diagonal \) float speed = u_Time * 1.5; vec2 rainUV = screenUV * 1.2 + vec2(speed * 0.4, -speed) + (smoothWalk * 0.05); // Leemos la textura de lluvia cargada en u_Tex1 vec4 RainTex = texture2D(u_Tex1, rainUV); // 4. EFECTO REBOTE (Splashes) // Generamos ondas circulares procedurales para simular el impacto en el suelo float splash = 0.0; vec2 splashGrid = fract(screenUV * 6.0 + vec2(u_Time * 0.1, 0.0)); float t = fract(u_Time * 3.0); if (t > 0.85) { float dist = length(splashGrid - 0.5); float circle = abs(dist - (t - 0.85) * 2.5); splash = smoothstep(0.04, 0.0, circle) * smoothstep(1.0, 0.85, t); } // Resultado Final // El canal rojo de la textura rain.png suele ser el que tiene la información de la gota. float intensity = RainTex.r * 0.8; vec3 rainColor = RainTex.rgb + (splash * 0.5); float opacity = 0.4; gl_FragColor = vec4(Game.rgb + rainColor * intensity * opacity, Game.a); }