// ====================================================================
// LensFlare.glsl - РЕАЛИСТИЧНЫЙ LENS FLARE ДЛЯ MINECRAFT ШЕЙДЕРА
// ====================================================================

// === НАСТРОЙКИ LENS FLARE ===
#define LENS_FLARE_ENABLED
#define LENS_FLARE_INTENSITY 1.0     // [0.0 0.25 0.5 0.75 1.0 1.25 1.5 2.0]
#define LENS_FLARE_GHOSTS 6          // [3 4 5 6 7 8] Количество ghost элементов
#define LENS_FLARE_GHOST_DISPERSAL 0.3  // [0.1 0.2 0.3 0.4 0.5] Разброс
#define LENS_FLARE_HALO_WIDTH 0.4    // [0.2 0.3 0.4 0.5 0.6] Ширина halo
#define LENS_FLARE_CHROMATIC 0.004   // [0.0 0.002 0.004 0.006 0.008] Хроматическая аберрация

// === Вспомогательные функции ===

// Получение позиции солнца на экране
vec2 GetSunScreenPosition(mat4 projection, mat4 modelView, vec3 sunVector) {
    vec4 sunClipSpace = projection * modelView * vec4(sunVector * 1000.0, 1.0);
    vec3 sunNDC = sunClipSpace.xyz / sunClipSpace.w;
    return sunNDC.xy * 0.5 + 0.5;
}

// Проверка видимости солнца
float GetSunVisibility(vec2 sunScreenPos) {
    // Солнце за экраном
    if (sunScreenPos.x < 0.0 || sunScreenPos.x > 1.0 ||
        sunScreenPos.y < 0.0 || sunScreenPos.y > 1.0) {
        return 0.0;
    }
    return 1.0;
}

// Текстура градиента для lens flare элементов
float LensFlareGradient(float dist, float radius, float smoothness) {
    return smoothstep(radius + smoothness, radius - smoothness, dist);
}

// Chromatic aberration для каждого канала
vec3 SampleBloomChromatic(sampler2D tex, vec2 coord, vec2 direction, float strength) {
    vec3 result;
    result.r = texture(tex, coord + direction * strength * 1.0).r;
    result.g = texture(tex, coord + direction * strength * 0.0).g;
    result.b = texture(tex, coord + direction * strength * -1.0).b;
    return result;
}

// === ГЛАВНАЯ ФУНКЦИЯ LENS FLARE ===

vec3 CalculateLensFlare(
    vec2 screenCoord, 
    vec2 sunScreenPos, 
    sampler2D bloomTex,
    float sunVisibility,
    float aspectRatio
) {
    vec3 lensFlare = vec3(0.0);
    
    if (sunVisibility < 0.01) return lensFlare;
    
    // Вектор от центра экрана к солнцу
    vec2 sunVector = sunScreenPos - vec2(0.5);
    
    // Корректировка на aspect ratio
    sunVector.x *= aspectRatio;
    
    float sunDist = length(sunVector);
    vec2 sunDir = normalize(sunVector);
    
    // Затухание по мере удаления солнца от центра
    float centerFalloff = 1.0 - smoothstep(0.0, 1.2, sunDist);
    
    // === 1. GHOST ЭЛЕМЕНТЫ (отражения линз) ===
    float ghostSpacing = LENS_FLARE_GHOST_DISPERSAL;
    
    for (int i = 0; i < LENS_FLARE_GHOSTS; i++) {
        float offset = float(i) * ghostSpacing;
        vec2 ghostPos = vec2(0.5) - sunVector * offset;
        
        // Коррекция координат с учетом aspect ratio
        vec2 ghostCoord = screenCoord;
        ghostCoord.x = (ghostCoord.x - 0.5) * aspectRatio + 0.5;
        
        vec2 ghostVector = ghostCoord;
        ghostVector.x = (ghostVector.x - 0.5) * aspectRatio + 0.5;
        ghostVector = ghostVector - ghostPos;
        
        float ghostDist = length(ghostVector);
        
        // Размер ghost зависит от индекса
        float ghostSize = 0.05 + float(i) * 0.015;
        
        // Радиальный градиент
        float ghostMask = LensFlareGradient(ghostDist, ghostSize, ghostSize * 0.3);
        
        // Цветовая вариация для каждого ghost
        vec3 ghostColor = vec3(1.0);
        if (i % 3 == 0) ghostColor = vec3(1.0, 0.8, 0.6); // Теплый
        else if (i % 3 == 1) ghostColor = vec3(0.6, 0.8, 1.0); // Холодный
        else ghostColor = vec3(0.8, 1.0, 0.7); // Зеленоватый
        
        // Хроматическая аберрация
        vec3 ghostSample = SampleBloomChromatic(
            bloomTex, 
            ghostPos, 
            normalize(ghostVector),
            LENS_FLARE_CHROMATIC * (1.0 + float(i) * 0.2)
        );
        
        lensFlare += ghostSample * ghostMask * ghostColor * 0.3;
    }
    
    // === 2. HALO (большое кольцо) ===
    vec2 haloCoord = screenCoord;
    haloCoord.x = (haloCoord.x - 0.5) * aspectRatio + 0.5;
    
    vec2 haloVector = haloCoord - vec2(0.5);
    float haloDist = length(haloVector);
    
    // Кольцо с заданной шириной
    float haloRadius = 0.5;
    float haloMask = abs(haloDist - haloRadius);
    haloMask = 1.0 - smoothstep(0.0, LENS_FLARE_HALO_WIDTH, haloMask);
    
    // Хроматическая аберрация для halo
    vec3 haloSample = SampleBloomChromatic(
        bloomTex,
        sunScreenPos,
        normalize(haloVector),
        LENS_FLARE_CHROMATIC * 2.0
    );
    
    lensFlare += haloSample * haloMask * vec3(0.6, 0.8, 1.0) * 0.15;
    
    // === 3. ЦЕНТРАЛЬНАЯ ВСПЫШКА (starburst) ===
    vec2 centerCoord = screenCoord;
    centerCoord.x = (centerCoord.x - 0.5) * aspectRatio + 0.5;
    
    vec2 centerVector = centerCoord - sunScreenPos;
    centerVector.x /= aspectRatio;
    
    float centerDist = length(centerVector);
    float centerMask = LensFlareGradient(centerDist, 0.03, 0.02);
    
    // Лучи (starburst pattern)
    float angle = atan(centerVector.y, centerVector.x);
    float rays = abs(sin(angle * 6.0)); // 6 лучей
    rays = pow(rays, 3.0);
    
    vec3 centerFlare = texture(bloomTex, sunScreenPos).rgb;
    lensFlare += centerFlare * centerMask * (1.0 + rays * 0.5) * vec3(1.0, 0.95, 0.9);
    
    // === 4. ДОПОЛНИТЕЛЬНЫЕ БЛИКИ ===
    
    // Маленький яркий блик рядом с солнцем
    vec2 smallGlarePos = vec2(0.5) - sunVector * 0.15;
    vec2 smallGlareVector = haloCoord - smallGlarePos;
    float smallGlareDist = length(smallGlareVector);
    float smallGlareMask = LensFlareGradient(smallGlareDist, 0.02, 0.015);
    
    vec3 smallGlare = texture(bloomTex, smallGlarePos).rgb;
    lensFlare += smallGlare * smallGlareMask * vec3(1.0, 0.9, 0.7) * 0.5;
    
    // === ФИНАЛЬНАЯ ОБРАБОТКА ===
    
    // Общая интенсивность
    lensFlare *= LENS_FLARE_INTENSITY;
    
    // Затухание от центра
    lensFlare *= centerFalloff;
    
    // Видимость солнца
    lensFlare *= sunVisibility;
    
    // Затухание в зависимости от времени суток (опционально)
    // lensFlare *= smoothstep(0.0, 0.2, dot(sunVector, sunVector));
    
    return max(lensFlare, vec3(0.0));
}

// === УПРОЩЕННАЯ ВЕРСИЯ (если нужна производительность) ===

vec3 CalculateLensFlareFast(
    vec2 screenCoord, 
    vec2 sunScreenPos,
    sampler2D bloomTex,
    float sunVisibility,
    float aspectRatio
) {
    if (sunVisibility < 0.01) return vec3(0.0);
    
    vec3 lensFlare = vec3(0.0);
    vec2 sunVector = sunScreenPos - vec2(0.5);
    sunVector.x *= aspectRatio;
    
    float sunDist = length(sunVector);
    float centerFalloff = 1.0 - smoothstep(0.0, 1.2, sunDist);
    
    // Только 3 ghost элемента
    for (int i = 0; i < 3; i++) {
        float offset = float(i) * 0.3;
        vec2 ghostPos = vec2(0.5) - sunVector * offset;
        
        vec2 ghostCoord = screenCoord;
        ghostCoord.x = (ghostCoord.x - 0.5) * aspectRatio + 0.5;
        ghostCoord = ghostCoord - ghostPos;
        
        float ghostDist = length(ghostCoord);
        float ghostSize = 0.05 + float(i) * 0.015;
        float ghostMask = LensFlareGradient(ghostDist, ghostSize, ghostSize * 0.3);
        
        vec3 ghostColor = (i == 0) ? vec3(1.0, 0.8, 0.6) : 
                         (i == 1) ? vec3(0.6, 0.8, 1.0) : 
                                    vec3(0.8, 1.0, 0.7);
        
        vec3 ghostSample = texture(bloomTex, ghostPos).rgb;
        lensFlare += ghostSample * ghostMask * ghostColor * 0.3;
    }
    
    // Центральная вспышка
    vec2 centerVector = screenCoord - sunScreenPos;
    float centerDist = length(centerVector);
    float centerMask = LensFlareGradient(centerDist, 0.03, 0.02);
    
    vec3 centerFlare = texture(bloomTex, sunScreenPos).rgb;
    lensFlare += centerFlare * centerMask * vec3(1.0, 0.95, 0.9);
    
    lensFlare *= LENS_FLARE_INTENSITY * centerFalloff * sunVisibility;
    
    return max(lensFlare, vec3(0.0));
}

