vec3 get_stars(vec3 PlayerPosN) {
    vec3 StarCoord = PlayerPosN / (PlayerPosN.y + length(PlayerPosN.xz));
    //StarCoord.x += frameTimeCounter * 0.001;
    const float ACTUAL_STAR_SIZE = 386;
    vec3 StarCoordFloor = floor(StarCoord * ACTUAL_STAR_SIZE) / ACTUAL_STAR_SIZE;
    vec3 StarCoordMid = StarCoordFloor + 0.5 / ACTUAL_STAR_SIZE;

    float Visibility = smoothstep(0, 0.1, StarCoord.y); // Smoothly fade out stars near the bottom of the sky
    Visibility *= max(0.5 - distance(StarCoordMid.xz, StarCoord.xz) * ACTUAL_STAR_SIZE, 0) * 2;

    float StarNoise = random(StarCoordFloor.xz);
    #ifdef RAINBOW_STARS
    vec3 StarColor = vec3(hash2(StarCoordFloor.xz), StarNoise);
    #else
    vec3 StarColor = vec3(0.5);
    #endif
    return vec3(max(0, StarNoise - 0.995) * 50 * Visibility * StarColor);
}

vec3 get_sky_overworld(vec3 ViewPosN, const bool DrawSun, float PlayerPosY) {
    vec3 UVW = to_uvw(cameraPosition.y * 5 + EarthRad, get_phi(ViewPosN), get_delta(sunPosN));
    UVW.y = SmoothMin(UVW.y, 0.46, 0.01);

    float VdotSun = dot(sunPosN, ViewPosN);

    vec3 RlhS = sample_scattering(UVW, false, true) * rayleigh_phase(VdotSun);
    vec3 MieS = sample_scattering(UVW, false, false) * cs_phase(VdotSun);

    vec3 SkyColor = RlhS + MieS;

    float VdotMoon = dot(-sunPosN, ViewPosN);
    UVW.z = to_uvw(0, 0, get_delta(-sunPosN)).z;

    RlhS = sample_scattering(UVW, true, true) * rayleigh_phase(VdotMoon);
    MieS = sample_scattering(UVW, true, false) * cs_phase(VdotMoon);

    SkyColor += RlhS + MieS;

    float Fade = smoothstep(-0.02, 0.1, PlayerPosY);

    if (DrawSun) {
        SkyColor += step(0.9998, VdotSun) * dataBuf.SunColor * Fade * 10;
        SkyColor += step(0.9997, VdotMoon) * dataBuf.MoonColor * Fade;
    }

    return SkyColor;
}

vec3 get_sky_nether() {
    vec3 fogColorL = pow(fogColor.rgb, vec3(2.2));
    vec3 SkyColor = fogColorL / get_luminance(fogColorL);
    return SkyColor / 100;
}

vec3 get_sky(vec3 ViewPosN, const bool DrawSun, float PlayerPosY) {
    #ifdef DIMENSION_OVERWORLD
    return get_sky_overworld(ViewPosN, DrawSun, PlayerPosY);
    #elif defined DIMENSION_NETHER
    return get_sky_nether();
    #else
    return vec3(1);
    #endif
}
