200 lines
6.4 KiB
GLSL
200 lines
6.4 KiB
GLSL
#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);
|
|
} |