﻿
====================
ARCHIVO: entity.properties
====================
# AquÃ­ mapeas las entidades para aplicarles efectos especiales
# entity.1 = minecraft:creeper
# entity.2 = minecraft:zombie

====================
ARCHIVO: final.fsh
====================
#version 330 compatibility

#include "/settings.glsl"

in vec2 TexCoords;
// Recibimos las variables calculadas en final.vsh (gran ganancia de FPS)
in float state;
in float dayNightSwap;

/* DRAWBUFFERS:0 */
out vec4 outColor0;

uniform float rainStrength;
uniform vec3 playerPosition;

// VARIABLE AÃ‘ADIDA: Llama al efecto de visiÃ³n nocturna de OptiFine/Iris
uniform float nightVision;

uniform sampler2D colortex0;
uniform sampler2D colortex2;
uniform sampler2D depthtex0;

uniform mat4 gbufferProjectionInverse;
uniform mat4 gbufferModelViewInverse;
uniform mat4 shadowModelView;
uniform mat4 shadowProjection;

#if ENABLE_SHADOW == 1
uniform sampler2D shadowtex0;

vec3 DistortPosition(vec3 p){
    p.xy *= inversesqrt(p.x*p.x + p.y*p.y + 0.01) * 0.909;
    p.z *= 0.5;
    return p;
}

float Visibility(in sampler2D ShadowMap, in vec3 SampleCoords, in vec3 WorldPosition) {
	float distance = length(WorldPosition - playerPosition);
	float bias = mix(0.0001, 0.003, min(1.0, distance / shadowDistance));
    return step(SampleCoords.z - bias, texture(ShadowMap, SampleCoords.xy).r);
}

vec3 GetShadow(float depth) {
    vec3 ClipSpace = vec3(TexCoords, depth) * 2.0f - 1.0f;
    vec4 ViewW = gbufferProjectionInverse * vec4(ClipSpace, 1.0f);
    vec3 View = ViewW.xyz / ViewW.w;
	
    vec4 World = gbufferModelViewInverse * vec4(View, 1.0f);
    vec4 ShadowSpace = shadowProjection * shadowModelView * World;
    ShadowSpace.xyz = DistortPosition(ShadowSpace.xyz);
    
    vec3 SampleCoords = ShadowSpace.xyz * 0.5f + 0.5f;
	vec3 CurrentSampleCoordinate = vec3(SampleCoords.xy, SampleCoords.z);
	vec3 ShadowAccum = mix(vec3(0.0f), vec3(1.0f), Visibility(shadowtex0, CurrentSampleCoordinate, World.xyz));
	
	float distanceShadowFade = length(View) / shadowDistance;
	float shadowFade = smoothstep(0.0, 1.0, 1.0 - distanceShadowFade);

	float t = 1.0 - shadowFade;
    float t2 = t * t;
    float t4 = t2 * t2;
    float t8 = t4 * t4;
    float fastPow = t8 * t2; 

    ShadowAccum = clamp(mix(vec3(1.0), ShadowAccum, 1.0 - fastPow), 0.0, 1.0);
    return ShadowAccum;
}
#endif

float AdjustLightmapTorch(in float torchLight) {
    return 2.0 * torchLight * torchLight * torchLight;
}

float AdjustLightmapSky(in float sky){
    float sky_2 = sky * sky;
    return sky_2 * sky_2;
}

vec2 AdjustLightmap(in vec2 Lightmap){
    return vec2(AdjustLightmapTorch(Lightmap.x), AdjustLightmapSky(Lightmap.y));
}

vec3 GetLightmapColor(in vec2 Lightmap){
    Lightmap = AdjustLightmap(Lightmap);
    vec3 SkyColor = vec3(0.09f, 0.17f, 0.3f); 
    
	#if ENABLE_SHADOW == 0
	SkyColor = vec3(1) * 0.1f;
	#endif
	
    vec3 TorchLighting = Lightmap.x * vec3(1.0f, 1.0f, 1.0f);
    vec3 SkyLighting = Lightmap.y * SkyColor * state * (1.0 - rainStrength);
	
	float occ = (Lightmap.y * LIGHT_ABSORPTION * state * (1.0 - rainStrength));
	float torchMask = smoothstep(-0.2, 0.8, Lightmap.x);
	TorchLighting -= occ * torchMask;
	
	vec3 LightmapLighting = clamp(TorchLighting * vec3(1.0f, 0.85f, 0.7f), 0.0f, 1.0f) + SkyLighting;
    return LightmapLighting;
}

#if FOG == 1
uniform int isEyeInWater;
uniform float near, far;
uniform float blindness;
uniform float darknessFactor;
uniform vec3 fogColor;

vec3 projectAndDivide(mat4 projectionMatrix, vec3 position){
	vec4 homPos = projectionMatrix * vec4(position, 1.0);
	return homPos.xyz / homPos.w;
}
#endif

void main(){
	vec3 Albedo = texture(colortex0, TexCoords).rgb;
	
// Si es el cielo (profundidad 1.0), saltamos cÃ¡lculos pesados
    float Depth = texture(depthtex0, TexCoords).r;
    if(Depth == 1.0) { 
        // =========================================================================
        // EL TRUCO DE LAS NUBES - VERSIÃ“N INFINITA
        // =========================================================================
        float diferenciaColor = abs(Albedo.r - Albedo.b);
        if (diferenciaColor < 0.1) {
            
            // 1. AJUSTE DE BRILLO
            float cloudBrightness = 1.15;
            Albedo = sqrt(Albedo) * cloudBrightness;
            
            // 2. TINTE NOCTURNO
            float isNight = 1.0 - state;
            vec3 nightCloudColor = vec3(0.3, 0.4, 0.5); 
            Albedo = mix(Albedo, Albedo * nightCloudColor, isNight);

            // 3. TRANSPARENCIA Y NIEBLA (Â¡AquÃ­ estÃ¡ el cambio!)
            // 0.95 = Cero niebla, nubes 100% sÃ³lidas e infinitas.
            // Si las sientes muy duras en los bordes lejanos, bÃ¡jalo a 0.95.
            float opacidadNubes = 1.0; 
            
            #if FOG == 1
            Albedo = mix(fogColor, Albedo, opacidadNubes);
            #else
            vec3 colorCieloFondo = vec3(0.4, 0.6, 0.9);
            Albedo = mix(colorCieloFondo, Albedo, opacidadNubes);
            #endif

            Albedo = clamp(Albedo, 0.0, 1.0);
        }
        
        outColor0 = vec4(Albedo, 1.0); 
        return; 
    }	
    // Leemos toda la informaciÃ³n de colortex2 (incluyendo el Alpha para las nubes)
    vec4 colortex2_data = texture(colortex2, TexCoords);
    vec2 Lightmap = colortex2_data.rg;
    
    // AQUÃ ESTÃ LA MAGIA: Si el alpha es 0, es una nube. Si es 1, es terreno.
    float isTerrain = colortex2_data.a; 

    vec3 Diffuse = Albedo;

    // SOLO aplicamos sombras, contraste y luz si es un bloque normal (isTerrain > 0.1)
    if (isTerrain > 0.1) {
        // Aumento de contraste (Acelerado por hardware con sqrt en lugar de pow)
        Diffuse *= Diffuse * sqrt(Diffuse);
        
        vec3 lightBrightnessV = vec3(0.1);
        vec3 ShadowColor = vec3(1.0);
        
        float adjLM = AdjustLightmapSky(Lightmap.y);
        vec3 LightmapColor = GetLightmapColor(Lightmap);
        
        // TRANSICIÃ“N SUAVIZADA: Ahora el oscurecimiento de las cuevas o lugares bajo techo serÃ¡ muy suave y natural.
        float skyLightMask = smoothstep(0.02, 0.40, Lightmap.y);

        #if SHADING == 1
        float lightBrightness = colortex2_data.z;
        lightBrightness *= state; 
        lightBrightness *= 1.0f - rainStrength;
        lightBrightness += (rainStrength - 0.5f) * (1.0f - state) * rainStrength;
        lightBrightnessV = vec3(lightBrightness) * state;
        
        #if CLASSIC_NIGHT == 0
        lightBrightnessV += vec3(0.0, 0.0, 0.5) * (1.0f - state);
        #endif
        #endif
        
        lightBrightnessV *= adjLM;
        // AQUÃ EL CAMBIO 1: Reducimos el brillo base de la noche en la superficie a 0.05f
        lightBrightnessV += mix(0.25f, 0.35f, state) * skyLightMask; 
        
        #if ENABLE_SHADOW == 1
        // OPTIMIZACIÃ“N: Verificamos que no sea la mano del jugador
        if (Depth >= 0.56) {
            vec3 originalShadow = GetShadow(Depth);
            float shadow_transperency_coef = mix(0.25, SHADOW_TRANSPARENCY, state);
            
            ShadowColor = mix(originalShadow * vec3(shadow_transperency_coef / 0.75), originalShadow, state);
            ShadowColor = mix(ShadowColor, vec3(1), dayNightSwap); 
            vec3 colorRainDayOrNight = mix(vec3(0.2), vec3(1), state);
            ShadowColor = mix(ShadowColor, colorRainDayOrNight, rainStrength);
        
            ShadowColor *= adjLM;
            ShadowColor += shadow_transperency_coef * skyLightMask; 
        }
        #endif
        
        // AQUÃ EL CAMBIO 2: Creamos la mÃ¡scara de cuevas
        float caveMask = 1.0 - skyLightMask;

        // Luz base dinÃ¡mica: 0.002 en la superficie (oscuridad pura) y 0.02,0.02,0.03 en la cueva
        vec3 baseAmbientLight = mix(vec3(0.025), vec3(0.020, 0.020, 0.030), caveMask);

        // =========================================================================
        // APLICANDO LA VISIÃ“N NOCTURNA
        // Inyecta luz pura a la luz ambiental base cuando te tomas la pociÃ³n
        // =========================================================================
        baseAmbientLight += vec3(0.5, 0.5, 0.6) * nightVision;
        
        Diffuse = clamp(Diffuse * (LightmapColor + lightBrightnessV * ShadowColor + baseAmbientLight), 0.0, 1.0);
        
        // =========================================================================
        // COLOR GRADING DIURNO Y NOCTURNO
        // =========================================================================
        float luminance = dot(Diffuse, vec3(0.299, 0.587, 0.114));
        
        // 1. DesaturaciÃ³n Diurna (2.5%)
        vec3 dayTint = mix(Diffuse, vec3(luminance), 0.05);
        Diffuse = mix(Diffuse, dayTint, state * skyLightMask);

        // 2. DesaturaciÃ³n y Tinte Nocturno (35% y tintes frÃ­os)
        float isNight = 1.0 - state; 
        vec3 nightTint = mix(Diffuse, vec3(luminance), 0.35); 
        nightTint *= vec3(0.70, 0.80, 1.35); 
        Diffuse = mix(Diffuse, nightTint, isNight * skyLightMask);
        // =========================================================================
    }

	#if FOG == 1
	vec3 NDCPos = vec3(TexCoords.xy, Depth) * 2.0 - 1.0;
	vec3 viewPos = projectAndDivide(gbufferProjectionInverse, NDCPos);
	
    float distance = length(viewPos);
    float currentFar = far * mix(mix(1.0, near * 0.5, blindness), near, darknessFactor);
    
    // AQUÃ ESTÃ EL ARREGLO DE LA NIEBLA
    // fogStart: Distancia a la que empieza (75% del lÃ­mite visual). Â¡Nada de niebla en la cara!
    float fogStart = currentFar * 0.75; 
    float fogEnd = currentFar;
    
    if (isEyeInWater == 1) {
        fogStart = 0.0; // Bajo el agua empieza inmediatamente
        fogEnd = 84.0;
    }
    
    // Calcula la niebla de forma lineal y luego la suaviza
    float fogValue = clamp((distance - fogStart) / (fogEnd - fogStart), 0.0, 1.0);
    fogValue = smoothstep(0.0, 1.0, fogValue); 
    
    vec3 finalFogColor = fogColor * fogColor * sqrt(fogColor);
    if(isEyeInWater == 1) finalFogColor *= 0.45; // Agua oscura
    
    Diffuse = mix(Diffuse, finalFogColor, fogValue);
	#endif
	
	// CorrecciÃ³n gamma final optimizada
	Diffuse = sqrt(Diffuse);
	outColor0 = vec4(Diffuse, 1.0);
}

====================
ARCHIVO: final.vsh
====================
#version 330 compatibility

// 'out' para enviar variables calculadas al Fragment Shader (final.fsh)
out vec2 TexCoords;

// Variables pre-calculadas en el Vertex Shader para ahorrar rendimiento
out float state;
out float dayNightSwap;

uniform int worldTime;

// OPTIMIZACIÃ“N: Mezcla suave entre horas. Calculado por vÃ©rtice en lugar de por pÃ­xel.
float smoothTransition(float time) {
    if (time >= 0.0 && time <= 1000.0) return time / 1000.0;
    else if (time < 12000.0) return 1.0;
    else if (time <= 13000.0) return 1.0 - (time - 12000.0) / 1000.0;
    else return 0.0;
}

// OPTIMIZACIÃ“N: TransiciÃ³n para sombras.
float swapDayNight(float time) {
	if (time >= 12300.0f && time <= 12800.0f) {
		return (time - 12300.0f) / 500.0f;
	} else if (time > 12800.0f && time <= 13200.0f) {
		return 1.0f - (time - 12800.0f) / 400.0f;
	} else if (time >= 22700.0f && time <= 23200.0f) {
		return (time - 22700.0f) / 500.0f;
	} else if (time > 23200.0f && time <= 23700.0f) {
		return 1.0f - (time - 23200.0f) / 500.0f;
	} else {
		return 0.0f;
	}
}

void main() {
   TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
   
   // LÃ³gica moderna: Reemplazamos ftransform() obsoleto
   gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
   
   // Ejecutamos las matemÃ¡ticas de tiempo y las exportamos
   state = smoothTransition(float(worldTime));
   dayNightSwap = swapDayNight(float(worldTime));
}

====================
ARCHIVO: gbuffers_armor_glint.fsh
====================
#version 330 compatibility

in vec2 TexCoords;
in vec4 Color;

uniform sampler2D gtexture;

/* DRAWBUFFERS:0 */
out vec4 outColor0;

void main(){
    vec4 albedo = texture(gtexture, TexCoords) * Color;
    outColor0 = albedo * 1.5; // Destello de encantamiento
}

====================
ARCHIVO: gbuffers_armor_glint.vsh
====================
#version 330 compatibility

out vec2 TexCoords;
out vec4 Color;

void main() {
	TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
	Color = gl_Color;
	gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}

====================
ARCHIVO: gbuffers_entities.fsh
====================
#version 330 compatibility

#include "/settings.glsl"

in vec2 TexCoords;
in vec2 LightmapCoords;
in vec4 Color;
in vec3 Normal;

uniform int entityId;
uniform sampler2D gtexture;
uniform vec3 shadowLightPosition;
uniform vec4 entityColor;
uniform mat4 gbufferModelViewInverse;

/* DRAWBUFFERS:02 */
out vec4 outColor0; 
out vec4 outColor1; 

void main(){
    vec4 albedo = texture(gtexture, TexCoords) * Color;
    
    if (albedo.a < 0.1) discard;
    
    // Tinte por recibir daÃ±o
	albedo.rgb = mix(albedo.rgb, entityColor.rgb, entityColor.a);
    
	vec3 shadowLightDir = normalize(mat3(gbufferModelViewInverse) * shadowLightPosition);
	float diffuseLight = clamp(dot(shadowLightDir, Normal), 0.0f, 1.0f);
    
    // Si es el jugador, iluminaciÃ³n plena
	if (int(entityId) == 1) {
		diffuseLight = 1.0;
	}
	
    outColor0 = albedo;
	outColor1 = vec4(LightmapCoords, diffuseLight, 1.0f);
}

====================
ARCHIVO: gbuffers_entities.vsh
====================
#version 330 compatibility

#include "/settings.glsl"

in vec4 at_tangent;
in vec3 mc_Entity;
uniform mat4 gbufferModelView;
uniform mat4 gbufferModelViewInverse;

out vec2 TexCoords;
out vec4 Color;
out vec2 LightmapCoords;
out vec3 Normal;

void main() {
	vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
    pos = (gbufferModelViewInverse * vec4(pos,1)).xyz;
	gl_Position = gl_ProjectionMatrix * gbufferModelView * vec4(pos,1);
    
    gl_FogFragCoord = length(pos);
	TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
	Normal = gl_Normal;
    
	LightmapCoords = mat2(gl_TextureMatrix[1]) * gl_MultiTexCoord1.xy;
    LightmapCoords = (LightmapCoords * 33.05f / 32.0f) - (1.05f / 32.0f);
	Color = gl_Color;
}

====================
ARCHIVO: gbuffers_hand.fsh
====================
#version 330 compatibility

in vec2 TexCoords;
in vec2 LightmapCoords;
in vec3 Normal;
in vec4 Color;

uniform sampler2D gtexture;
uniform vec3 shadowLightPosition;
uniform mat4 gbufferModelViewInverse;
uniform vec3 sunPosition;

/* DRAWBUFFERS:02 */
out vec4 outColor0;
out vec4 outColor1;

void main(){
    vec4 albedo = texture(gtexture, TexCoords) * Color;
	
    if (albedo.a < 0.1) discard;

	vec3 shadowLightDir = normalize(mat3(gbufferModelViewInverse) * shadowLightPosition);
	float diffuseLight = 0.75f * clamp(4.0f * dot(Normal, normalize(sunPosition)), 0.0f, 1.0f) + 0.05;
    
    outColor0 = albedo;
    outColor1 = vec4(LightmapCoords, diffuseLight, 1.0f);
}

====================
ARCHIVO: gbuffers_hand.vsh
====================
#version 330 compatibility

out vec2 TexCoords;
out vec3 Normal;
out vec4 Color;
out vec2 LightmapCoords;

void main() {
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; 
	TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
	
    LightmapCoords = mat2(gl_TextureMatrix[1]) * gl_MultiTexCoord1.st;
	LightmapCoords = (LightmapCoords * 33.05f / 32.0f) - (1.05f / 32.0f);
	
    Normal = gl_NormalMatrix * gl_Normal;
    Color = gl_Color;
}

====================
ARCHIVO: gbuffers_skybasic.fsh
====================
#version 330 compatibility

uniform mat4 gbufferModelView;
uniform vec3 fogColor;
uniform vec3 skyColor;
uniform int isEyeInWater;

in vec2 starData; 
in vec4 Color;
in vec3 viewPos; // Recibido del vertex shader

/* DRAWBUFFERS:0 */
out vec4 outColor0;

// FunciÃ³n para crear el degradado del horizonte
float fogify(float x, float w) {
	return w / (x * x + w);
}

void main() {
	vec3 finalColor;

	if(isEyeInWater == 1) {
		finalColor = fogColor;
	}
	else if (starData.g > 0.5) {
		// Es una estrella
		finalColor = vec3(starData.r * 0.65); 
	}
	else {
		// Es el cielo: Calculamos el degradado basado en la direcciÃ³n del vÃ©rtice (viewPos)
		vec3 direction = normalize(viewPos);
		float upDot = dot(direction, gbufferModelView[1].xyz);
		finalColor = mix(skyColor, fogColor, fogify(max(upDot, 0.0), 0.05));
	}
	
    outColor0 = vec4(finalColor, 1.0f);
}

====================
ARCHIVO: gbuffers_skybasic.vsh
====================
#version 330 compatibility

out vec2 starData;
out vec4 Color;
out vec3 viewPos; // Enviamos la posiciÃ³n al fragment para calcular el degradado

uniform mat4 gbufferModelView;
uniform mat4 gbufferModelViewInverse;

void main() {
    // Calculamos la posiciÃ³n del vÃ©rtice
    vec4 position = gl_ModelViewMatrix * gl_Vertex;
    gl_Position = gl_ProjectionMatrix * position;
    
    // viewPos servirÃ¡ para calcular el color del cielo sin usar gl_FragCoord
    viewPos = position.xyz;
    
    // DetecciÃ³n de estrellas: si el color es blanco/gris puro y no es negro
	starData = vec2(gl_Color.r, float(gl_Color.r == gl_Color.g && gl_Color.g == gl_Color.b && gl_Color.r > 0.0));
	
	Color = gl_Color;
}

====================
ARCHIVO: gbuffers_skytextured.fsh
====================
#version 330 compatibility

uniform sampler2D gtexture;
uniform float rainStrength;

in vec2 TexCoords;

/* DRAWBUFFERS:0 */
out vec4 outColor0;

void main() {
	vec4 color = texture(gtexture, TexCoords);
	color.a *= 1.0 - rainStrength; // Oculta el sol/luna si llueve
	outColor0 = color;
}

====================
ARCHIVO: gbuffers_skytextured.vsh
====================
#version 330 compatibility

out vec2 TexCoords;

void main() {
	gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
	TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
}

====================
ARCHIVO: gbuffers_terrain.fsh
====================
#version 330 compatibility

#include "/settings.glsl"

in vec2 TexCoords;
in vec2 LightmapCoords;
in vec3 foliageColor;
in vec3 Normal;

uniform sampler2D gtexture;
uniform int isEyeInWater;
uniform vec3 shadowLightPosition;
uniform mat4 gbufferModelViewInverse;

/* DRAWBUFFERS:02 */
out vec4 outColor0;
out vec4 outColor1;

void main() {
    vec4 outputColorData = texture(gtexture, TexCoords);
    
    // Transparencia (Alpha test)
    if (outputColorData.a < 0.1) {
        discard;
    }
    
	vec3 albedo = outputColorData.rgb * foliageColor;
	float lightBrightness = 0.0f;
	vec2 LC = LightmapCoords;
    
	if(isEyeInWater == 1) {
		LC += vec2(0.2f); // Agua
	}
	else if (isEyeInWater == 2) {
		albedo = vec3(0.6, 0.1, 0.0); // Lava
	}
	
	vec3 shadowLightDir = normalize(mat3(gbufferModelViewInverse) * shadowLightPosition);
	lightBrightness = clamp(dot(shadowLightDir, Normal), 0.0f, 1.0f);

    outColor0 = vec4(albedo, outputColorData.a);
	outColor1 = vec4(LC, lightBrightness, 1.0f);
}

====================
ARCHIVO: gbuffers_terrain.vsh
====================
#version 330 compatibility

#include "/settings.glsl"

in vec4 at_tangent;
in vec3 mc_Entity;

uniform mat4 gbufferModelView;
uniform mat4 gbufferModelViewInverse;

out vec2 TexCoords;
out vec3 foliageColor;
out vec2 LightmapCoords;
out vec3 Normal;

uniform int worldTime;

void main() {
    // ProyecciÃ³n del terreno
	vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
    pos = (gbufferModelViewInverse * vec4(pos,1)).xyz;
	gl_Position = gl_ProjectionMatrix * gbufferModelView * vec4(pos,1);
    
    gl_FogFragCoord = length(pos);
	TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
	Normal = gl_Normal;
    
	LightmapCoords = mat2(gl_TextureMatrix[1]) * gl_MultiTexCoord1.xy;
    LightmapCoords = (LightmapCoords * 33.05f / 32.0f) - (1.05f / 32.0f);
    
	foliageColor = gl_Color.rgb;
}

====================
ARCHIVO: gbuffers_textured.fsh
====================
#version 330 compatibility

in vec2 TexCoords;
in vec4 Color;

uniform sampler2D gtexture;

/* DRAWBUFFERS:0 */
out vec4 outColor0;

void main(){
    vec4 albedo = texture(gtexture, TexCoords) * Color;
    if (albedo.a < 0.1) discard;
    outColor0 = albedo;
}

====================
ARCHIVO: gbuffers_textured.vsh
====================
#version 330 compatibility

out vec2 TexCoords;
out vec4 Color;

void main() {
	TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
    Color = gl_Color;
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}

====================
ARCHIVO: gbuffers_textured_lit.fsh
====================
#version 330 compatibility

in vec2 TexCoords;
in vec4 Color;

uniform sampler2D gtexture;

/* DRAWBUFFERS:02 */
out vec4 outColor0;
out vec4 outColor1;

void main(){
    vec4 albedo = texture(gtexture, TexCoords);
	albedo.rgb *= Color.rgb;
    
	outColor0 = albedo;
    outColor1 = vec4(1.0f, 1.0f, 0.0f, 1.0f); // Evita oscurecimiento por sombra
}

====================
ARCHIVO: gbuffers_textured_lit.vsh
====================
#version 330 compatibility

out vec2 TexCoords;
out vec4 Color;

void main() {
	TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
    Color = gl_Color;
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}

====================
ARCHIVO: gbuffers_water.fsh
====================
#version 330 compatibility

#include "/settings.glsl"

in vec2 TexCoords;
in vec2 LightmapCoords;
in vec3 foliageColor;
in vec3 tangent;
in vec3 viewSpaceGeoNormal;
in float blockId;

uniform sampler2D gtexture;
uniform sampler2D normals;
uniform sampler2D specular;
uniform sampler2D noisetex;
uniform vec3 cameraPosition;
uniform vec3 shadowLightPosition;
uniform float frameTimeCounter;
uniform mat4 gbufferModelViewInverse;

/* DRAWBUFFERS:02 */
out vec4 outColor0;
out vec4 outColor1;

void main(){
    vec4 outputColorData = texture(gtexture, TexCoords);
	vec3 albedo = outputColorData.rgb * foliageColor;
	float diffuseLight = 0.25;
	vec3 shadowLightDir = normalize(mat3(gbufferModelViewInverse) * shadowLightPosition);
	
    // Detectamos si es bloque de agua (id 1000 general en modders)
	if (int(blockId + 0.5) == 1000) {
		outputColorData.a = 0.9f; 
		diffuseLight = clamp(dot(shadowLightDir, viewSpaceGeoNormal), 0.0f, 1.0f);
    }
	
    outColor0 = vec4(albedo, outputColorData.a);
	outColor1 = vec4(LightmapCoords, diffuseLight, outputColorData.a);
}

====================
ARCHIVO: gbuffers_water.vsh
====================
#version 330 compatibility

#include "/settings.glsl"

in vec4 at_tangent;
in vec3 mc_Entity;

uniform vec3 cameraPosition;
uniform mat4 gbufferModelView;
uniform mat4 gbufferModelViewInverse;

out vec2 TexCoords;
out vec3 foliageColor;
out vec2 LightmapCoords;
out vec3 tangent;
out vec3 viewSpaceGeoNormal;
out float blockId;

void main() {
	blockId = mc_Entity.x;
	tangent = gl_NormalMatrix * at_tangent.xyz;

	vec3 pos = (gl_ModelViewMatrix * gl_Vertex).xyz;
	pos = (gbufferModelViewInverse * vec4(pos,1)).xyz;
	
    gl_Position = gl_ProjectionMatrix * gbufferModelView * vec4(pos,1);
    gl_FogFragCoord = length(pos);
	
	TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
	viewSpaceGeoNormal = gl_NormalMatrix * gl_Normal;
	
    LightmapCoords = mat2(gl_TextureMatrix[1]) * gl_MultiTexCoord1.xy;
	LightmapCoords = (LightmapCoords * 33.05f / 32.0f) - (1.05f / 32.0f);
	
	foliageColor = gl_Color.rgb;
}

====================
ARCHIVO: gbuffers_weather.fsh
====================
#version 330 compatibility

in vec2 TexCoords;
in vec4 Color;

uniform sampler2D gtexture;
uniform float rainStrength;

/* DRAWBUFFERS:0 */
out vec4 outColor0;

void main(){
	vec4 albedo = vec4(0.0);
	albedo.a = texture(gtexture, TexCoords).a;
	
	if (albedo.a > 0.001) {
		albedo.rgb = texture(gtexture, TexCoords).rgb;
        
		albedo.a *= 0.45 * rainStrength * length(albedo.rgb / 3.0) * float(albedo.a > 0.1);
		albedo.rgb = sqrt(albedo.rgb); // OptimizaciÃ³n
		albedo.rgb *= vec3(0.43, 0.63, 0.81); // Tinte frÃ­o de lluvia

		#if MC_VERSION < 10800
		albedo.a *= 4.0;
		albedo.rgb *= 0.525;
		#endif
		
		#if ALPHA_BLEND == 0
		albedo.rgb = sqrt(max(albedo.rgb, vec3(0.0)));
		albedo.a *= 2.0;
		#endif
	}
	
	outColor0 = albedo;
}

====================
ARCHIVO: gbuffers_weather.vsh
====================
#version 330 compatibility

out vec2 TexCoords;
out vec4 Color;

void main() {
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex; 
    TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
    Color = gl_Color;
}

====================
ARCHIVO: settings.glsl
====================
// Efecto de Niebla (Siempre Activo - Oculto en menÃº)
#define FOG 1                           
// CorrecciÃ³n de nubes (Fijo)
#define NEW_LIGHTING 1                  

// Configuraciones de IluminaciÃ³n y Sombras
#define ENABLE_SHADOW 1                 // Siempre Activo
#define CLASSIC_NIGHT 1                 // Noche Original (1) o Azulada (0) [0 1]
#define LIGHT_ABSORPTION 0.70           // AbsorciÃ³n de luz       [0.00 0.10 0.20 0.30 0.40 0.50 0.60 0.70 0.80 0.90 1.00 1.10 1.20 1.30 1.40 1.50 1.60 1.70 1.80 1.90 2.00]
#define SHADOW_TRANSPARENCY 0.15        // Transparencia Sombras  [0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.935 0.95 1.00]

// Variables de mundo
const float sunPathRotation = 15.0;      // Ãngulo del sol         [-90.0 -75.0 -60.0 -45.0 -30.0 -15.0 0.0 15.0 30.0 45.0 60.0 75.0 90.0]
const float shadowDistance = 160.0;      // Distancia Sombras      [64.0 80.0 96.0 112.0 128.0 160.0 192.0 224.0 256.0 320.0 384.0 512.0 768.0 1024.0]
const int shadowMapResolution = 1536;   // ResoluciÃ³n Sombras     [512 768 1024 1536 2048 3072 4096 8192]

const float shadowDistanceRenderMul = 1.0;

// Opciones aÃ±adidas para OclusiÃ³n Ambiental
const float ambientOcclusionLevel = 0.50; // Nivel de OclusiÃ³n   [0.00 0.10 0.20 0.30 0.40 0.50 0.60 0.65 0.70 0.80 0.90 1.00]

====================
ARCHIVO: shaders.properties
====================
oldLighting=false
oldHandLight=false
shadow.culling=true
frustum.culling=true

# MenÃº con OclusiÃ³n Ambiental aÃ±adida (y aÃ±adimos ALPHA_BLEND)
screen=FOG_DISTANCE SHADING LIGHT_ABSORPTION ALPHA_BLEND ambientOcclusionLevel SHADOW_TRANSPARENCY sunPathRotation shadowDistance shadowMapResolution

# Registramos el slider
sliders=FOG_DISTANCE ambientOcclusionLevel shadowMapResolution shadowDistance sunPathRotation SHADOW_TRANSPARENCY LIGHT_ABSORPTION

====================
ARCHIVO: shadow.fsh
====================
#version 330 compatibility

in vec2 TexCoords;
in vec4 Color;

uniform sampler2D gtexture;

/* DRAWBUFFERS:0 */
out vec4 outColor0;

void main() {
    vec4 col = texture(gtexture, TexCoords) * Color;
    
    // Transparencia en el mapa de sombras
    if(col.a < 0.1) discard;
    
    outColor0 = col;
}

====================
ARCHIVO: shadow.vsh
====================
#version 330 compatibility

out vec2 TexCoords;
out vec4 Color;

vec3 DistortPosition(vec3 p){
    p.xy *= inversesqrt(p.x*p.x + p.y*p.y + 0.01) * 0.909;
    p.z *= 0.5;
    return p;
}

void main(){
    TexCoords = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
    Color = gl_Color;
    
    // ProyecciÃ³n ajustada
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
    gl_Position.xyz = DistortPosition(gl_Position.xyz);
}
