/*
============================================================
AURORA SUNSET — lib/sky.glsl
------------------------------------------------------------
Stylized sky + light colors, tuned to match the target
screenshot ("pastel dream dusk"):
* luminous violet zenith
* lavender-pink mid sky
* cream-pink horizon, cream-gold glow around the sun
* three-lobe sun glow (wide flood + halo + hot core)
* dusk lingers longer than vanilla (wider time window)
DIMENSION ROUTING — Iris and OptiFine define exactly one
WORLD_* macro per dimension (WORLD_NETHER, WORLD_END; the
overworld gets neither). The Nether / End branches below
carry the same blood-red / blue-black palettes as
shaders/world-1/lib/sky.glsl and shaders/world1/lib/sky.glsl,
so every loader resolves the right sky no matter which
folder its include resolution prefers. The test suite
asserts the two copies never drift apart.
Requires lib/common.glsl + lib/settings.glsl to be included
first.
============================================================
*/
#ifndef INCLUDE_SKY
#define INCLUDE_SKY
/* w = (dayWeight, duskWeight, nightWeight), sums to 1.
The dusk window is deliberately wide: the violet/gold mood
starts before sunset and lingers after. */
vec3 skyTimeWeights(float sunH) {
#ifdef WORLD_NETHER
/* The Nether has no day cycle: fixed weight set (day, dusk, night) */
return vec3(0.0, 0.60, 0.40);
#else
#ifdef WORLD_END
/* The End has no day cycle: night-leaning weights */
return vec3(0.0, 0.15, 0.85);
#else
float dayF = smoothstep(0.05, 0.42, sunH);
float nightF = smoothstep(0.05, 0.42, -sunH);
float duskF = clamp(1.0 - dayF - nightF, 0.0, 1.0) * SUNSET_STRENGTH;
float total = max(dayF + duskF + nightF, 1e-4);
return vec3(dayF, duskF, nightF) / total;
#endif
#endif
}
/* Direct light color: soft white by day, peach at dusk, dim moon blue */
vec3 sunLightColor(vec3 w) {
#ifdef WORLD_NETHER
/* dim ember — the Nether has no sun; keeps compiled-but-unexecuted paths consistent */
return vec3(0.85, 0.32, 0.16) * 0.35;
#else
#ifdef WORLD_END
/* faint cool light — the End has no sun */
return vec3(0.45, 0.55, 0.85) * 0.20;
#else
return vec3(1.00, 0.96, 0.88) * w.x
+ vec3(1.00, 0.80, 0.55) * w.y
+ vec3(0.38, 0.46, 0.68) * w.z * 0.38;
#endif
#endif
}
/*
The stylized sky. dir & sunDir are unit vectors in world space.
Overworld layers (dusk):
1. 4-stop vertical gradient violet -> lavender -> cream-pink
2. sun-azimuth warm band cream turns golden toward the sun
3. three-lobe sun glow wide flood + mid halo + hot core
4. moon halo / rain wash / void sink
*/
vec3 skyGradient(vec3 dir, vec3 sunDir, vec3 w) {
#ifdef WORLD_NETHER
/* NETHER: blackened ember charcoal top, dark crimson mid,
blood-red horizon with a soft ember glow all around —
no sun direction, the horizon burns evenly. */
float h = dir.y;
float hUp = clamp(h, 0.0, 1.0);
float belowF = smoothstep(0.00, 0.35, -h);
vec3 zenith = vec3(0.050, 0.014, 0.014); /* blackened ember */
vec3 mid = vec3(0.170, 0.034, 0.030); /* dark crimson */
vec3 horizon = vec3(0.470, 0.090, 0.052); /* blood red */
float midF = smoothstep(0.52, 0.08, hUp);
float horF = smoothstep(0.30, 0.02, hUp);
vec3 col = mix(zenith, mid, midF);
col = mix(col, horizon, horF * 0.90);
/* soft ember glow all around the horizon */
col += vec3(0.55, 0.14, 0.06) * horF * 0.35;
/* sink into the dark below the horizon */
col *= 1.0 - 0.45 * belowF;
return col;
#else
#ifdef WORLD_END
/* END: blue-black void. Near-black top, restrained
desaturated blue toward the horizon. No stars. */
float h = dir.y;
float hUp = clamp(h, 0.0, 1.0);
float belowF = smoothstep(0.00, 0.35, -h);
vec3 zenith = vec3(0.012, 0.014, 0.034); /* blue-black */
vec3 mid = vec3(0.024, 0.030, 0.060); /* deep navy */
vec3 horizon = vec3(0.060, 0.078, 0.135); /* dark desaturated blue */
float midF = smoothstep(0.52, 0.08, hUp);
float horF = smoothstep(0.30, 0.02, hUp);
vec3 col = mix(zenith, mid, midF);
col = mix(col, horizon, horF * 0.90);
/* whisper of blue lift along the horizon */
col += vec3(0.10, 0.14, 0.24) * horF * 0.30;
/* sink into the void below */
col *= 1.0 - 0.50 * belowF;
return col;
#else
float h = dir.y;
float hUp = clamp(h, 0.0, 1.0);
float belowF = smoothstep(0.00, 0.35, -h);
/* ---- 1. vertical gradients ---- */
vec3 dayCol = mix(vec3(0.66, 0.80, 0.93), vec3(0.18, 0.42, 0.78), smoothstep(0.0, 0.55, hUp));
vec3 duskZenith = vec3(0.260, 0.220, 0.660); /* luminous violet-blue */
vec3 duskMid = vec3(0.740, 0.520, 0.800); /* lavender-pink */
vec3 duskHor = vec3(1.000, 0.800, 0.720); /* cream-pink */
float midF = smoothstep(0.52, 0.08, hUp); /* rises to horizon */
float horF = smoothstep(0.30, 0.02, hUp);
vec3 duskCol = mix(duskZenith, duskMid, midF);
duskCol = mix(duskCol, duskHor, horF * 0.90);
vec3 nightCol = mix(vec3(0.055, 0.065, 0.125), vec3(0.012, 0.016, 0.048), hUp);
vec3 col = dayCol * w.x + duskCol * w.y + nightCol * w.z;
/* ---- 2. sun-azimuth warm band (strongest low, toward the sun) ---- */
vec2 dirXZ = normalize(dir.xz + vec2(1e-5, 0.0));
vec2 sunXZ = normalize(sunDir.xz + vec2(1e-5, 0.0));
float azim = max(dot(dirXZ, sunXZ), 0.0);
float band = pow(azim, 2.5) * horF;
col = mix(col, vec3(1.08, 0.90, 0.64), band * 0.85 * w.y);
/* ---- 3. the BIG sunset glow (cream, not ember) ---- */
float cosSun = max(dot(dir, sunDir), 0.0);
float gWide = pow(cosSun, 2.0); /* floods half the sky */
float gMid = pow(cosSun, 6.0); /* halo */
float gCore = pow(cosSun, 40.0); /* hot center */
col += (vec3(1.06, 0.84, 0.60) * gWide * 0.62
+ vec3(1.16, 0.98, 0.70) * gMid * 0.88
+ vec3(1.28, 1.16, 0.88) * gCore * 1.30) * w.y;
/* by day, a milder warm breath around the sun near the horizon */
col += vec3(1.00, 0.85, 0.60) * gMid * horF * 0.16 * w.x;
/* ---- 4. moon halo ---- */
col += vec3(0.48, 0.55, 0.80)
* pow(max(dot(dir, -sunDir), 0.0), 42.0) * w.z * 0.55;
/* sink into the void below the horizon */
col *= 1.0 - 0.55 * belowF;
/* rain washes the mood out */
col = mix(col, vec3(luma(col)) * vec3(0.75, 0.80, 0.88), rainStrength * 0.75);
return col;
#endif
#endif
}
/*
Fog / haze color along a view direction. skyGradient already
turns cream-gold toward the sun, so distance haze automatically
reads golden on the sun side and violet on the shadow side.
Dimension branches mirror their world-folder lib files exactly.
*/
vec3 skyFogColor(vec3 viewDirW, vec3 sunDir, vec3 w) {
#ifdef WORLD_NETHER
/* Crimson distance haze: terrain melts into the red. */
return skyGradient(viewDirW, sunDir, w) * 1.05;
#else
#ifdef WORLD_END
/* Dark-blue distance haze: far end-stone melts into the void. */
return skyGradient(viewDirW, sunDir, w) * 1.05;
#else
return skyGradient(viewDirW, sunDir, w) * 1.06;
#endif
#endif
}
#endif