2026-02-21 19:41:21 -08:00
|
|
|
#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 horizonColor;
|
|
|
|
|
vec4 zenithColor;
|
|
|
|
|
float timeOfDay;
|
|
|
|
|
} push;
|
|
|
|
|
|
2026-02-21 21:57:16 -08:00
|
|
|
layout(location = 0) in vec2 TexCoord;
|
2026-02-21 19:41:21 -08:00
|
|
|
|
|
|
|
|
layout(location = 0) out vec4 outColor;
|
|
|
|
|
|
|
|
|
|
void main() {
|
2026-02-21 21:57:16 -08:00
|
|
|
// Reconstruct world-space ray direction from screen position.
|
|
|
|
|
// TexCoord is [0,1]^2; convert to NDC [-1,1]^2.
|
|
|
|
|
float ndcX = TexCoord.x * 2.0 - 1.0;
|
|
|
|
|
float ndcY = -(TexCoord.y * 2.0 - 1.0); // flip Y: Vulkan NDC Y-down, but projection already flipped
|
|
|
|
|
|
|
|
|
|
// Unproject to view space using focal lengths from projection matrix.
|
|
|
|
|
// projection[0][0] = 2*near/(right-left) = 1/tan(fovX/2)
|
|
|
|
|
// projection[1][1] = 2*near/(top-bottom) (already negated for Vulkan Y-flip)
|
|
|
|
|
// We want the original magnitude, so take abs to get the focal length.
|
|
|
|
|
vec3 viewDir = vec3(ndcX / projection[0][0],
|
|
|
|
|
ndcY / abs(projection[1][1]),
|
|
|
|
|
-1.0);
|
|
|
|
|
|
|
|
|
|
// Rotate to world space: view = R*T, so R^-1 = R^T = transpose(mat3(view))
|
|
|
|
|
mat3 invViewRot = transpose(mat3(view));
|
|
|
|
|
vec3 worldDir = normalize(invViewRot * viewDir);
|
|
|
|
|
|
|
|
|
|
// worldDir.z = sin(elevation); +1 = zenith, 0 = horizon, -1 = nadir
|
|
|
|
|
float t = clamp(worldDir.z, 0.0, 1.0);
|
2026-02-21 19:41:21 -08:00
|
|
|
t = pow(t, 1.5);
|
|
|
|
|
vec3 sky = mix(push.horizonColor.rgb, push.zenithColor.rgb, t);
|
|
|
|
|
float scatter = max(0.0, 1.0 - t * 2.0) * 0.15;
|
|
|
|
|
sky += vec3(scatter * 0.8, scatter * 0.4, scatter * 0.1);
|
|
|
|
|
outColor = vec4(sky, 1.0);
|
|
|
|
|
}
|