//precisionhighp float;

// Фрагментный шейдер:
uniform vec3 uColor;
uniform float uDistanceToPlanetSurface; // Расстояние корабля до поверхности

// Константы затухания, определенные прямо в шейдере
const float DIST_FOG_MAX = 2000.0;
const float DIST_FOG_MIN = 1000.0;

varying vec3 vWorldNormal; 
varying vec3 vViewNormal;
varying vec3 vViewPosition;


// Добавь эти uniform-ы
//uniform float uTime;
uniform vec3 uLightDirView;
uniform vec3 uPlayerDirWorld; 

// Простая функция псевдослучайного шума
float hash(float n) { return fract(sin(n) * 43758.5453123); }

float noise(vec3 x) {
    vec3 p = floor(x);
    vec3 f = fract(x);
    f = f * f * (3.0 - 2.0 * f);
    float n = p.x + p.y * 57.0 + 113.0 * p.z;
    return mix(mix(mix(hash(n + 0.0), hash(n + 1.0), f.x),
                   mix(hash(n + 57.0), hash(n + 58.0), f.x), f.y),
               mix(mix(hash(n + 113.0), hash(n + 114.0), f.x),
                   mix(hash(n + 170.0), hash(n + 171.0), f.x), f.y), f.z);
}

// Fractal Brownian Motion для "кучевости" облаков
float fbm(vec3 p) {
    float f = 0.5000 * noise(p); p *= 2.02;
    f += 0.2500 * noise(p); p *= 2.03;
    f += 0.1250 * noise(p);
    return f;
}

void main()
{
//gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);

    vec3 normal = normalize(vViewNormal);
    vec3 viewVector = normalize(-vViewPosition);
    float NdotV = dot(normal, viewVector);

    // Вектор направления от центра планеты к текущему фрагменту атмосферы (Мировой)
    vec3 fragmentDir = normalize(vWorldNormal);
    // Вектор направления от центра планеты к игроку (нужно передать как uniform)
    // Передай его в C++: renderer.RenderUniform3fv("uPlayerDirWorld", playerDirWorld.data());
    

    // --- 1. Плавное отсечение за горизонтом (Horizon Mask) ---
    // Считаем косинус угла между игроком и точкой атмосферы
    float cosAngle = dot(fragmentDir, uPlayerDirWorld);
    // Плавно затухаем от 0.0 (горизонт) до 0.2 (над головой)
    //float horizonMask = smoothstep(0.0, 0.4, cosAngle);
	float horizonMask = smoothstep(0.93, 1.0, cosAngle);


    // --- 2. Плавный переход при прохождении сквозь слой (Transition Mask) ---
    // Определяем "высоту" игрока относительно слоя (напр. слой на 1.03 * R)
    // uDistanceToPlanetSurface уже вычислен в PlanetData
    float layerHeight = 600.0; // Примерная толщина слоя атмосферы (3% от 20000)
    
    // Делаем прозрачным при приближении к границе (dist около layerHeight)
    // и снова видимым, когда спустились ниже
    float distToLayer = abs(uDistanceToPlanetSurface - layerHeight);
    float transitionMask = smoothstep(0.0, 200.0, distToLayer); 

    // --- 3. Освещение и облака ---
    float diff = max(dot(normal, uLightDirView), 0.0);
    if (uDistanceToPlanetSurface < layerHeight) {
        diff = max(dot(-normal, uLightDirView), 0.0); // Инверсия для взгляда снизу
    }
    float lightIntensity = diff + 0.05;

    vec3 cloudCoord = fragmentDir * 6.0; 
    //cloudCoord.x += uTime * 0.03;
    float n = fbm(cloudCoord);
    float cloudMask = smoothstep(0.4, 0.65, n);

    // --- 4. Финальный расчет альфы ---
    float atmosphereDensity = pow(1.0 - abs(NdotV), 5.0);
    float distanceFactor = clamp((uDistanceToPlanetSurface - DIST_FOG_MIN) / (DIST_FOG_MAX - DIST_FOG_MIN), 0.0, 1.0);
    
    // Базовая прозрачность облаков
    float cloudAlpha = cloudMask * 0.8;
    
    // Применяем маски:
    // В космосе важен distanceFactor, на планете важен horizonMask
    float finalCloudAlpha = cloudAlpha * transitionMask;
    if (uDistanceToPlanetSurface < layerHeight) {
        finalCloudAlpha *= horizonMask; // На планете скрываем то, что под ногами
    } else {
        finalCloudAlpha *= distanceFactor; // В космосе скрываем по вашей старой логике
		if (NdotV <=0.0)
		{
			//finalCloudAlpha = 0.0;
			discard;
		}
    }

    vec3 currentAtmo = mix(vec3(0.01, 0.02, 0.1), uColor, lightIntensity);
    vec3 currentCloud = mix(vec3(0.1, 0.1, 0.15), vec3(1.0, 1.0, 1.0), lightIntensity);
    vec3 finalRGB = mix(currentAtmo, currentCloud, cloudMask);
	//vec3 finalRGB = currentAtmo;

    // Для дымки (atmo) оставляем затухание при посадке
    float atmoAlpha = atmosphereDensity * distanceFactor;
	//float atmoAlpha = distanceFactor;
	
	float finalAtmoAlpha = atmoAlpha;

	if (uDistanceToPlanetSurface < layerHeight) {
		finalCloudAlpha *= horizonMask;
		finalAtmoAlpha *= horizonMask; // Принудительно гасим дымку под горизонтом
	}

	gl_FragColor = vec4(finalRGB, max(finalAtmoAlpha, finalCloudAlpha));
}