mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-25 16:30:15 +00:00
Skybox: replace sphere-mesh approach with a fullscreen triangle that reconstructs the world-space ray direction analytically via inverse projection/view matrices. Eliminates clip.w=0 degeneracy at the horizon and correctly maps altitude to dir.z in the Z-up coordinate system. Clouds: hemisphere mesh was storing altitude in aPos.y (Y-up convention); the Z-up view matrix projected this sideways, making clouds appear vertical. Store altitude in aPos.z and update the fragment shader to read dir.z as altitude and dir.xy as the horizontal UV plane.
51 lines
1.7 KiB
GLSL
51 lines
1.7 KiB
GLSL
#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;
|
|
|
|
layout(location = 0) in vec2 TexCoord;
|
|
|
|
layout(location = 0) out vec4 outColor;
|
|
|
|
void main() {
|
|
// 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);
|
|
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);
|
|
}
|