#version 450 // Static-map model vertex stage. Draws the world-space triangle soup built by // ra3::models (buildings and props the map places) against the exact camera the // terrain raymarcher uses, so both passes share one projection and depth test. // // The camera is passed as its orthonormal basis so the same math as // terrain.frag applies: ndc.x = dot(r, right) / (a * tan(fov/2) * aspect), // ndc.y = -dot(r, up) / (a * tan(fov/2)), depth = (a - NEAR) / (FAR - NEAR) // with `a = dot(r, fwd)` the view-space depth. layout(location = 0) in vec3 in_pos; layout(location = 1) in vec3 in_normal; layout(location = 2) in vec2 in_uv; layout(location = 3) in float in_layer; layout(push_constant) uniform Push { vec4 cam_pos; // xyz = eye position vec4 fwd; // xyz = forward vec4 right; // xyz = right, w = tan(fov / 2) vec4 up; // xyz = up, w = tan(fov / 2) * aspect vec4 sun; // xyz = sun direction, w = ambient } pc; layout(location = 0) out vec2 out_uv; layout(location = 1) out vec3 out_normal; layout(location = 2) flat out float out_layer; const float NEAR = 10.0; const float FAR = 60000.0; void main() { vec3 r = in_pos - pc.cam_pos.xyz; float a = dot(r, pc.fwd.xyz); float b = dot(r, pc.right.xyz); float c = dot(r, pc.up.xyz); float th = pc.right.w; float th_aspect = pc.up.w; float depth = clamp((a - NEAR) / (FAR - NEAR), 0.0, 1.0); gl_Position = vec4(b / th_aspect, -c / th, depth * a, a); out_uv = in_uv; out_normal = in_normal; out_layer = in_layer; }