Kelsidavis-WoWee/assets/shaders/skybox.frag.glsl

98 lines
3.3 KiB
Text
Raw Normal View History

#version 450
layout(set = 0, binding = 0) uniform PerFrame {
mat4 view;
mat4 projection;
mat4 lightSpaceMatrix;
vec4 lightDir;
vec4 lightColor;
vec4 ambientColor;
vec4 viewPos;
vec4 fogColor;
vec4 fogParams;
vec4 shadowParams;
};
layout(push_constant) uniform Push {
vec4 zenithColor; // DBC skyTopColor
vec4 midColor; // DBC skyMiddleColor
vec4 horizonColor; // DBC skyBand1Color
vec4 fogColorPush; // DBC skyBand2Color
vec4 sunDirAndTime; // xyz = sun direction, w = timeOfDay
} push;
layout(location = 0) in vec2 TexCoord;
layout(location = 0) out vec4 outColor;
void main() {
// Reconstruct world-space ray direction from screen position.
float ndcX = TexCoord.x * 2.0 - 1.0;
float ndcY = -(TexCoord.y * 2.0 - 1.0);
vec3 viewDir = vec3(ndcX / projection[0][0],
ndcY / abs(projection[1][1]),
-1.0);
mat3 invViewRot = transpose(mat3(view));
vec3 worldDir = normalize(invViewRot * viewDir);
vec3 sunDir = push.sunDirAndTime.xyz;
float timeOfDay = push.sunDirAndTime.w;
// Elevation: +1 = zenith, 0 = horizon, -1 = nadir
float elev = worldDir.z;
float elevClamped = clamp(elev, 0.0, 1.0);
// --- 3-band sky gradient using DBC colors ---
// Zenith dominates upper sky, mid color fills the middle,
// horizon band at the bottom with a thin fog fringe.
vec3 sky;
if (elevClamped > 0.4) {
// Upper sky: mid -> zenith
float t = (elevClamped - 0.4) / 0.6;
sky = mix(push.midColor.rgb, push.zenithColor.rgb, t);
} else if (elevClamped > 0.05) {
// Lower sky: horizon -> mid (wide band)
float t = (elevClamped - 0.05) / 0.35;
sky = mix(push.horizonColor.rgb, push.midColor.rgb, t);
} else {
// Thin fog fringe right at horizon
float t = elevClamped / 0.05;
sky = mix(push.fogColorPush.rgb, push.horizonColor.rgb, t);
}
// --- Below-horizon darkening (nadir) ---
if (elev < 0.0) {
float nadirFade = clamp(-elev * 3.0, 0.0, 1.0);
vec3 nadirColor = push.fogColorPush.rgb * 0.3;
sky = mix(push.fogColorPush.rgb, nadirColor, nadirFade);
}
// --- Rayleigh-like scattering (subtle warm glow near sun) ---
float sunDot = max(dot(worldDir, sunDir), 0.0);
float sunAboveHorizon = clamp(sunDir.z, 0.0, 1.0);
float rayleighStrength = pow(1.0 - elevClamped, 3.0) * 0.15;
vec3 scatterColor = mix(vec3(0.8, 0.45, 0.15), vec3(0.3, 0.5, 1.0), elevClamped);
sky += scatterColor * rayleighStrength * sunDot * sunAboveHorizon;
// --- Mie-like forward scatter (sun disk glow) ---
float mieSharp = pow(sunDot, 64.0) * 0.4;
float mieSoft = pow(sunDot, 8.0) * 0.1;
vec3 sunGlowColor = mix(vec3(1.0, 0.85, 0.55), vec3(1.0, 1.0, 0.95), elevClamped);
sky += sunGlowColor * (mieSharp + mieSoft) * sunAboveHorizon;
// --- Subtle horizon haze ---
float hazeDensity = exp(-elevClamped * 12.0) * 0.06;
sky += push.horizonColor.rgb * hazeDensity * sunAboveHorizon;
// --- Night: slight moonlight tint ---
if (sunDir.z < 0.0) {
float moonlight = clamp(-sunDir.z * 0.5, 0.0, 0.15);
sky += vec3(0.02, 0.03, 0.08) * moonlight;
}
outColor = vec4(sky, 1.0);
}