// Преобразуем дефайны из свойств в удобные векторы
const vec3 waterScattering = vec3(WATER_COLOR_R, WATER_COLOR_G, WATER_COLOR_B);
const vec3 waterAbsorptionRGB = vec3(WATER_ABSORB_R, WATER_ABSORB_G, WATER_ABSORB_B);

const vec3 dirtScattering = vec3(DIRT_COLOR_R, DIRT_COLOR_G, DIRT_COLOR_B);
const vec3 dirtAbsorptionRGB = vec3(DIRT_ABSORB_R, DIRT_ABSORB_G, DIRT_ABSORB_B);

void WaterFog(inout vec3 color, in TranslucentMask mask, in float waterSkylight, in float LdotV, in float waterDepth) {
    // Базовая плотность тумана с учетом дождя и льда
    float fogDensity = mix(WATER_FOG_DENSITY * fma(0.1, wetnessCustom * eyeSkylightFix, 0.16), 0.5, mask.ice) * waterDepth;
    
    #if defined IS_OVERWORLD
        // Bliss-style: Динамическое смешивание чистой воды и грязи во время дождя
        vec3 currentScattering = mix(waterScattering, dirtScattering, wetnessCustom * 0.8);
        vec3 currentAbsorption = mix(waterAbsorptionRGB, dirtAbsorptionRGB, wetnessCustom * 0.8);

        // Базовое освещение воды от неба
        vec3 waterFogColor = mix(skyIlluminance * 0.4, vec3(GetLuminance(skyIlluminance) * 0.1), 0.8 * wetnessCustom * eyeSkylightFix) * rPI;
        
        // Добавляем фазу рассеивания (солнечные блики в толще воды)
        float scatter = HenyeyGreensteinPhase(LdotV, 0.65) + 0.1 * rPI;
        waterFogColor *= currentScattering * (1.0 + 28.0 * oneMinus(wetnessCustom * 0.8) * directIlluminance * scatter);
    #else
        // Настройки для Незера и Энда
        vec3 waterFogColor = waterScattering * rPI;
        vec3 currentAbsorption = waterAbsorptionRGB;
        vec3 currentScattering = waterScattering;
    #endif

    // Высчитываем коэффициент экстинкции (свет, который не дошел до глаза)
    // Экстинкция = Абсорбция + Рассеивание
    vec3 extinction = (currentAbsorption * 8.0 + currentScattering * 2.0 + 0.03);
    
    // Рассчитываем пропускание света (Transmittance) по каналам RGB
    vec3 transmittance = fastExp(-extinction * fogDensity);
    
    // Применяем к итоговому цвету
    color *= transmittance;
    color += waterFogColor * waterSkylight * oneMinus(transmittance);
}

void UnderwaterFog(inout vec3 color, in TranslucentMask mask, in float waterDepth) {
    // Плотность для зрения под водой
    float fogDensity = mix(WATER_FOG_DENSITY * fma(0.05, wetnessCustom * eyeSkylightFix, 0.1), 0.5, mask.ice) * waterDepth;
    
    #if defined IS_OVERWORLD
        vec3 currentScattering = mix(waterScattering, dirtScattering, wetnessCustom * 0.8);
        vec3 currentAbsorption = mix(waterAbsorptionRGB, dirtAbsorptionRGB, wetnessCustom * 0.8);

        vec3 waterFogColor = mix(skyIlluminance * 0.4, vec3(GetLuminance(skyIlluminance) * 0.1), 0.8 * wetnessCustom * eyeSkylightFix) * rPI;
        waterFogColor *= currentScattering;
    #else
        vec3 waterFogColor = waterScattering * rPI;
        vec3 currentAbsorption = waterAbsorptionRGB;
        vec3 currentScattering = waterScattering;
    #endif

    // Подводная экстинкция
    vec3 extinction = (currentAbsorption * 8.0 + currentScattering * 2.0 + 0.03);
    vec3 transmittance = fastExp(-extinction * max(fogDensity, 2.0) + 0.4);
    
    color *= transmittance;
    color += waterFogColor * saturate(eyeSkylightFix + 0.2) * oneMinus(transmittance);
}