diff --git a/gameengine/packages/quake3/shaders/spirv/bsp.frag.glsl b/gameengine/packages/quake3/shaders/spirv/bsp.frag.glsl new file mode 100644 index 000000000..01e716dec --- /dev/null +++ b/gameengine/packages/quake3/shaders/spirv/bsp.frag.glsl @@ -0,0 +1,49 @@ +#version 450 + +// Quake 3 BSP fragment shader (minimal). +// Q3 bakes radiosity into a lightmap atlas at compile time, so runtime lighting +// is just: albedo × lightmap × overbright. The classic Q3 "overbright bits = 1" +// doubles lightmap intensity — modern screens are brighter, so we expose it as +// part of the existing FragmentUniformData.material slot (z) with a 2.0 default. +// +// Fragment sampler bindings come from workflow_draw_map_step.cpp BSP path: +// set=2 binding=0 albedo (per-surface diffuse from extracted pk3 textures) +// set=2 binding=1 shadowMap (shadow map — ignored for BSP, lightmap is canonical) +// set=2 binding=2 lightmap (shared atlas built by bsp.lightmap_atlas) + +layout(set = 2, binding = 0) uniform sampler2D albedoTex; +layout(set = 2, binding = 1) uniform sampler2D shadowMap; +layout(set = 2, binding = 2) uniform sampler2D lightmapTex; + +layout(set = 3, binding = 0) uniform PBRUniforms { + vec4 u_lightDir; + vec4 u_lightColor; // a = exposure + vec4 u_ambient; + vec4 u_material; // z = lightmap overbright multiplier (defaults via C++) + vec4 u_flashPos; + vec4 u_flashDir; + vec4 u_flashColor; +}; + +layout(location = 0) in vec2 v_uv; +layout(location = 1) in vec2 v_lmuv; +layout(location = 2) in vec3 v_worldNormal; +layout(location = 3) in vec3 v_worldPos; +layout(location = 4) in vec3 v_cameraPos; + +layout(location = 0) out vec4 o_color; + +void main() { + vec3 albedo = texture(albedoTex, v_uv).rgb; + vec3 lightmap = texture(lightmapTex, v_lmuv).rgb; + + // Q3 overbright. material.z falls back to 2.0 (engine pushes 0 today, so + // fall through to a sane default rather than rendering a black map). + float overbright = (u_material.z > 0.0) ? u_material.z : 2.0; + + vec3 ambient = u_ambient.rgb * albedo; + vec3 lit = albedo * lightmap * overbright + ambient; + + float exposure = (u_lightColor.a > 0.0) ? u_lightColor.a : 1.0; + o_color = vec4(lit * exposure, 1.0); +} diff --git a/gameengine/packages/quake3/shaders/spirv/bsp.frag.spv b/gameengine/packages/quake3/shaders/spirv/bsp.frag.spv new file mode 100644 index 000000000..372002ca5 Binary files /dev/null and b/gameengine/packages/quake3/shaders/spirv/bsp.frag.spv differ diff --git a/gameengine/packages/quake3/shaders/spirv/bsp.vert.glsl b/gameengine/packages/quake3/shaders/spirv/bsp.vert.glsl new file mode 100644 index 000000000..82a1f641e --- /dev/null +++ b/gameengine/packages/quake3/shaders/spirv/bsp.vert.glsl @@ -0,0 +1,40 @@ +#version 450 + +// Quake 3 BSP vertex shader (minimal). +// Vertex format `position_uv_lmuv_normal` (BspRenderVertex): +// loc 0: vec3 position +// loc 1: vec2 diffuse uv +// loc 2: vec2 lightmap uv (already atlas-remapped by bsp.lightmap_atlas step) +// loc 3: vec3 world-space normal +// Uniform layout matches sdl3cpp::services::rendering::VertexUniformData +// so the same C++ uniform push call used by the seed pipeline works here. + +layout(location = 0) in vec3 a_position; +layout(location = 1) in vec2 a_uv; +layout(location = 2) in vec2 a_lmuv; +layout(location = 3) in vec3 a_normal; + +layout(set = 1, binding = 0) uniform VertexUniforms { + mat4 u_modelViewProj; + mat4 u_model; + vec4 u_surfaceNormal; // unused for BSP — per-vertex normal wins + vec4 u_uvScale; + vec4 u_cameraPos; + mat4 u_shadowVP; // unused for BSP — lightmap already encodes shadowing +}; + +layout(location = 0) out vec2 v_uv; +layout(location = 1) out vec2 v_lmuv; +layout(location = 2) out vec3 v_worldNormal; +layout(location = 3) out vec3 v_worldPos; +layout(location = 4) out vec3 v_cameraPos; + +void main() { + gl_Position = u_modelViewProj * vec4(a_position, 1.0); + v_uv = a_uv * u_uvScale.xy; + v_lmuv = a_lmuv; + vec4 wp = u_model * vec4(a_position, 1.0); + v_worldPos = wp.xyz; + v_worldNormal = mat3(u_model) * a_normal; + v_cameraPos = u_cameraPos.xyz; +} diff --git a/gameengine/packages/quake3/shaders/spirv/bsp.vert.spv b/gameengine/packages/quake3/shaders/spirv/bsp.vert.spv new file mode 100644 index 000000000..b894e15c9 Binary files /dev/null and b/gameengine/packages/quake3/shaders/spirv/bsp.vert.spv differ