OGRE_NATIVE_GLSL_VERSION_DIRECTIVE
#include <OgreUnifiedShader.h>

OGRE_UNIFORMS(
	uniform vec3 uDayTop;
	uniform vec3 uDayBottom;
	uniform vec3 uNightTop;
	uniform vec3 uNightBottom;
	uniform vec3 uSunriseColor;
	uniform vec3 uSunsetColor;
	uniform vec3 uSunDir;
	uniform float uSunElev;
	uniform float uSunSize;
	uniform float uMoonSize;
	uniform float uStarsEnabled;
)

IN(vec3 vWorldPos, TEXCOORD0)

// Simple pseudo-random function for stars
float hash(vec2 p)
{
	return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}

MAIN_DECLARATION
{
	vec3 dir = normalize(vWorldPos);
	float y = dir.y;

	// Sky gradient factor based on elevation
	float gradT = clamp(y * 0.5 + 0.5, 0.0, 1.0);

	// Day / night interpolation based on sun elevation
	// uSunElev: -1.0 = midnight, 0.0 = horizon, 1.0 = noon
	float dayFactor = smoothstep(-0.15, 0.25, uSunElev);
	float nightFactor = 1.0 - smoothstep(-0.25, 0.15, uSunElev);

	vec3 daySky = mix(uDayBottom, uDayTop, gradT);
	vec3 nightSky = mix(uNightBottom, uNightTop, gradT);

	vec3 skyColor = mix(nightSky, daySky, dayFactor);

	// Horizon glow for sunrise / sunset
	float horizon = 1.0 - abs(y);
	horizon = horizon * horizon;

	// Sunrise when sun is rising (uSunElev near 0, morning)
	// Sunset when sun is setting (uSunElev near 0, evening)
	// We approximate by checking if sun is near horizon
	float nearHorizon = 1.0 - smoothstep(0.0, 0.3, abs(uSunElev));
	vec3 glowColor = mix(uSunriseColor, uSunsetColor,
			     smoothstep(-0.1, 0.1, uSunDir.x));
	skyColor += glowColor * nearHorizon * horizon * 0.8;

	// Sun disc
	vec3 sunPos = -uSunDir;
	float sunDot = max(0.0, dot(dir, sunPos));
	float sunDisc = pow(sunDot, 1.0 / uSunSize);
	skyColor += vec3(1.0, 0.95, 0.8) * sunDisc * dayFactor;

	// Moon disc (opposite to sun)
	vec3 moonPos = uSunDir;
	float moonDot = max(0.0, dot(dir, moonPos));
	float moonDisc = pow(moonDot, 1.0 / uMoonSize);
	skyColor += vec3(0.85, 0.85, 0.95) * moonDisc * nightFactor;

	// Simple stars
	if (uStarsEnabled > 0.5) {
		float starNoise = hash(floor(dir.xz * 80.0));
		float star = smoothstep(0.995, 1.0, starNoise);
		// Only show stars at night and above horizon
		float starMask = nightFactor * smoothstep(-0.2, 0.1, y);
		skyColor += vec3(1.0, 1.0, 1.0) * star * starMask * 0.8;
	}

	gl_FragColor = vec4(skyColor, 1.0);
}
