mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 15:50:20 +00:00
- Skybox now uses DBC sky colors (skyTop/skyMiddle/skyBand1/skyBand2) instead of hardcoded C++ color curves, with 3-band gradient and Rayleigh/Mie scattering - Clouds receive sun direction for lit edges, self-shadowing, and silver lining - Fixed sun quad box artifact with proper edge fade in celestial shader - Lens flare attenuated by fog, cloud density, and weather intensity - Replaced garish green/purple lens flare ghosts with warm natural palette - Added zone-based weather system for single-player mode with per-zone rain/snow configuration, probability-based activation, and smooth intensity transitions - Server SMSG_WEATHER remains authoritative when connected to a server
104 lines
3.4 KiB
GLSL
104 lines
3.4 KiB
GLSL
#version 450
|
|
|
|
layout(push_constant) uniform Push {
|
|
vec4 cloudColor; // xyz = DBC-derived base cloud color, w = unused
|
|
vec4 sunDirDensity; // xyz = sun direction, w = density
|
|
vec4 windAndLight; // x = windOffset, y = sunIntensity, z = ambient, w = unused
|
|
} push;
|
|
|
|
layout(location = 0) in vec3 vWorldDir;
|
|
|
|
layout(location = 0) out vec4 outColor;
|
|
|
|
// --- Gradient noise (smoother than hash-based) ---
|
|
vec2 hash2(vec2 p) {
|
|
p = vec2(dot(p, vec2(127.1, 311.7)),
|
|
dot(p, vec2(269.5, 183.3)));
|
|
return fract(sin(p) * 43758.5453);
|
|
}
|
|
|
|
float gradientNoise(vec2 p) {
|
|
vec2 i = floor(p);
|
|
vec2 f = fract(p);
|
|
|
|
// Quintic interpolation for smoother results
|
|
vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);
|
|
|
|
float a = dot(hash2(i + vec2(0.0, 0.0)) * 2.0 - 1.0, f - vec2(0.0, 0.0));
|
|
float b = dot(hash2(i + vec2(1.0, 0.0)) * 2.0 - 1.0, f - vec2(1.0, 0.0));
|
|
float c = dot(hash2(i + vec2(0.0, 1.0)) * 2.0 - 1.0, f - vec2(0.0, 1.0));
|
|
float d = dot(hash2(i + vec2(1.0, 1.0)) * 2.0 - 1.0, f - vec2(1.0, 1.0));
|
|
|
|
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y) * 0.5 + 0.5;
|
|
}
|
|
|
|
float fbm(vec2 p) {
|
|
float val = 0.0;
|
|
float amp = 0.5;
|
|
for (int i = 0; i < 6; i++) {
|
|
val += amp * gradientNoise(p);
|
|
p *= 2.0;
|
|
amp *= 0.5;
|
|
}
|
|
return val;
|
|
}
|
|
|
|
void main() {
|
|
vec3 dir = normalize(vWorldDir);
|
|
float altitude = dir.z;
|
|
if (altitude < 0.0) discard;
|
|
|
|
vec3 sunDir = push.sunDirDensity.xyz;
|
|
float density = push.sunDirDensity.w;
|
|
float windOffset = push.windAndLight.x;
|
|
float sunIntensity = push.windAndLight.y;
|
|
float ambient = push.windAndLight.z;
|
|
|
|
vec2 uv = dir.xy / (altitude + 0.001);
|
|
uv += windOffset;
|
|
|
|
// --- 6-octave FBM for cloud shape ---
|
|
float cloud1 = fbm(uv * 0.8);
|
|
float cloud2 = fbm(uv * 1.6 + 5.0);
|
|
float cloud = cloud1 * 0.7 + cloud2 * 0.3;
|
|
|
|
// Coverage control: base coverage with detail erosion
|
|
float baseCoverage = smoothstep(0.30, 0.55, cloud);
|
|
float detailErosion = gradientNoise(uv * 4.0);
|
|
cloud = baseCoverage * smoothstep(0.2, 0.5, detailErosion);
|
|
cloud *= density;
|
|
|
|
// Horizon fade
|
|
float horizonFade = smoothstep(0.0, 0.15, altitude);
|
|
cloud *= horizonFade;
|
|
|
|
if (cloud < 0.01) discard;
|
|
|
|
// --- Sun lighting on clouds ---
|
|
// Sun dot product for view-relative brightness
|
|
float sunDot = max(dot(vec3(0.0, 0.0, 1.0), sunDir), 0.0);
|
|
|
|
// Self-shadowing: sample noise offset toward sun direction, darken if occluded
|
|
float lightSample = fbm((uv + sunDir.xy * 0.05) * 0.8);
|
|
float shadow = smoothstep(0.3, 0.7, lightSample);
|
|
|
|
// Base lit color: mix dark (shadow) and bright (sunlit) based on shadow and sun
|
|
vec3 baseColor = push.cloudColor.rgb;
|
|
vec3 shadowColor = baseColor * (ambient * 0.8);
|
|
vec3 litColor = baseColor * (ambient + sunIntensity * 0.6);
|
|
vec3 cloudRgb = mix(shadowColor, litColor, shadow * sunDot);
|
|
|
|
// Add ambient fill so clouds aren't too dark
|
|
cloudRgb = mix(baseColor * ambient, cloudRgb, 0.7 + 0.3 * sunIntensity);
|
|
|
|
// --- Silver lining effect at cloud edges ---
|
|
float edgeLight = smoothstep(0.0, 0.3, cloud) * (1.0 - smoothstep(0.3, 0.8, cloud));
|
|
cloudRgb += vec3(1.0, 0.95, 0.9) * edgeLight * sunDot * sunIntensity * 0.4;
|
|
|
|
// --- Edge softness for alpha ---
|
|
float edgeSoftness = smoothstep(0.0, 0.3, cloud);
|
|
float alpha = cloud * edgeSoftness;
|
|
|
|
if (alpha < 0.01) discard;
|
|
outColor = vec4(cloudRgb, alpha);
|
|
}
|