#version 330 // Input vertex attributes (from vertex shader) in vec3 fragPosition; in vec2 fragTexCoord; in vec4 fragColor; in vec3 fragNormal; in vec3 worldPos; // Input uniform values uniform sampler2D texture0; uniform vec4 colDiffuse; // Custom uniforms for sky uniform vec3 horizonColor; uniform vec3 zenithColor; uniform vec3 sunDirection; uniform vec3 sunColor; uniform float sunIntensity; uniform vec3 moonDirection; uniform vec3 moonColor; uniform float moonIntensity; uniform float moonPhase; uniform float starsIntensity; uniform float time; // Output fragment color out vec4 finalColor; // Simple hash function for stars float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); } // Noise function for clouds float noise(vec2 p) { vec2 i = floor(p); vec2 f = fract(p); // Four corners in 2D of a tile float a = hash(i); float b = hash(i + vec2(1.0, 0.0)); float c = hash(i + vec2(0.0, 1.0)); float d = hash(i + vec2(1.0, 1.0)); // Smooth interpolation vec2 u = f * f * (3.0 - 2.0 * f); return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } // Fractal brownian motion for cloud shapes float fbm(vec2 p) { float value = 0.0; float amplitude = 0.5; float frequency = 2.0; for (int i = 0; i < 3; i++) { value += amplitude * noise(p * frequency); amplitude *= 0.5; frequency *= 2.0; } return value; } void main() { // Normalize the world position to get direction from center vec3 direction = normalize(worldPos); // Calculate gradient based on Y component (height) float gradientFactor = smoothstep(-0.5, 1.0, direction.y); // Interpolate between horizon and zenith colors vec3 skyColor = mix(horizonColor, zenithColor, gradientFactor); // Simple cloud layer (only during day) if (direction.y > 0.1 && sunIntensity > 0.2) { // Map direction to 2D cloud coordinates vec2 cloudCoord = direction.xz / max(direction.y, 0.001) * 0.5; // Animate clouds cloudCoord += vec2(time * 0.02, time * 0.01); // Generate cloud pattern using multiple layers of noise float cloudNoise = 0.0; cloudNoise += fbm(cloudCoord * 2.0) * 0.5; cloudNoise += fbm(cloudCoord * 5.0) * 0.25; cloudNoise += fbm(cloudCoord * 11.0) * 0.125; // Shape the clouds float cloudDensity = smoothstep(0.4, 0.6, cloudNoise); // Fade clouds at horizon cloudDensity *= smoothstep(0.0, 0.3, direction.y); if (cloudDensity > 0.01) { // Simple cloud lighting float lightness = 0.7 + 0.3 * sunIntensity; // Make clouds slightly bluish in shadow, whiter in light vec3 cloudColor = mix( vec3(0.7, 0.75, 0.85), // Shadow color vec3(1.0, 1.0, 1.0), // Lit color lightness ); // Mix clouds with sky skyColor = mix(skyColor, cloudColor, cloudDensity * 0.8); } } // Add stars (only visible at night) if (starsIntensity > 0.01 && direction.y > -0.1) { // Don't render stars below horizon // Create a simple star field using noise vec2 starCoord = direction.xz * 30.0; // Less dense grid // Two layers of stars for depth (reduced from 3) for (int i = 0; i < 2; i++) { vec2 gridPos = floor(starCoord * (1.0 + float(i) * 0.3)); vec2 gridFract = fract(starCoord * (1.0 + float(i) * 0.3)); float starRandom = hash(gridPos + vec2(float(i) * 13.0, float(i) * 17.0)); // Much fewer stars (higher threshold) if (starRandom > 0.985 + float(i) * 0.005) { float starBrightness = hash(gridPos + vec2(37.0, 73.0)); // Circular star points vec2 starCenter = vec2(0.5); float dist = length(gridFract - starCenter); if (dist < 0.05) { // Slightly larger star points float starAlpha = pow(1.0 - dist / 0.05, 1.5) * starsIntensity; starAlpha *= (0.4 + starBrightness * 0.6); // Vary brightness skyColor = mix(skyColor, vec3(0.95, 0.95, 1.0), starAlpha); } } } } vec3 color = skyColor; // Calculate sun contribution vec3 sunDir = normalize(sunDirection); float sunDot = dot(direction, sunDir); // Only render sun if it's above horizon and has intensity if (sunDir.y > 0.0 && sunIntensity > 0.1) { // Sun disc with soft edges - much smaller float sunSize = 0.9985; // Much smaller sun (closer to 1.0 = smaller) float sunEdge = 0.997; if (sunDot > sunSize) { // Bright sun core color = mix(sunColor, vec3(1.0, 1.0, 0.95), 0.8); } else if (sunDot > sunEdge) { // Soft edge float edge = smoothstep(sunEdge, sunSize, sunDot); color = mix(color, sunColor, edge); } // Sun glow - tighter radius if (sunDot > 0.94) { float glow = pow(max(0.0, (sunDot - 0.94) / 0.06), 2.0) * sunIntensity; color = mix(color, sunColor, glow * 0.4); } } // Calculate moon contribution vec3 moonDir = normalize(moonDirection); float moonDot = dot(direction, moonDir); // Only render moon if it's above horizon if (moonDir.y > 0.0 && moonIntensity > 0.1) { // Moon disc - 15% smaller than before float moonSize = 0.9992; // Much smaller than sun (sun is 0.9985) float moonEdge = 0.999; if (moonDot > moonSize) { // Simple moon disc (simplified for smaller size) color = mix(color, moonColor, moonIntensity); } else if (moonDot > moonEdge) { // Soft moon edge float edge = smoothstep(moonEdge, moonSize, moonDot); color = mix(color, moonColor * 0.8, edge * moonIntensity); } // Subtle moon glow - even tighter for smaller moon if (moonDot > 0.98) { float glow = pow(max(0.0, (moonDot - 0.98) / 0.02), 2.0) * moonIntensity; color = mix(color, moonColor, glow * 0.1); } } finalColor = vec4(color, 1.0); }