Rendering: prefiltered cubemap IBL (replace equirect-mip specular approximation)
Current State
#135 (closed) implemented image-based lighting (IBL) + skybox, but deliberately skipped cubemap conversion: the engine had zero cubemap/compute-shader infrastructure (SDL_GPU_TEXTURETYPE_CUBE exists in the vendored SDL3 GPU headers, but nothing in subsystems/render/pipeline.zig ever creates one), and building a full equirect→cubemap conversion pass was a much larger scope than "add IBL to Bistro."
What shipped instead (#135 (closed))
- Skybox: sample the equirect HDR texture directly by view-ray direction (no cubemap needed — equirect direction→UV mapping works fine standalone).
- Diffuse irradiance: order-2 spherical harmonics, projected on the CPU once per environment texture upload (
subsystems/render/assets.zig'scomputeIrradianceSh). - Specular: reuse the equirect texture's own auto-generated mip chain (
SDL_GenerateMipmapsForGPUTexture), sampled viatextureLodkeyed by roughness — a stand-in for a real prefiltered cubemap. - BRDF term: Karis' analytic environment-BRDF polynomial approximation instead of a baked 2D LUT.
Gap
The mip-chain-of-the-equirect approximation for specular has real quality issues a true implementation would fix:
- Equirect pole distortion — mip generation box-filters in UV space, which over-blurs near the poles and under-blurs at the equator relative to true solid-angle-uniform filtering.
- No real GGX importance-sampled prefiltering — reflections at moderate roughness don't get the correct lobe shape, especially at grazing angles.
- No genuine parallax-free assumption fix — a real cubemap pipeline is also the natural place to eventually add reflection probes / local cubemap capture, if that's ever wanted.
Scope for this issue
- Add a
SDL_GPU_TEXTURETYPE_CUBErender-to-cubemap pass converting the equirect environment to 6 faces (fullscreen-triangle-per-face, sampling equirect by reconstructed direction). - GGX-importance-sampled specular prefiltering per mip level (the standard split-sum approach), replacing the equirect-mip stand-in.
- Baked 2D BRDF LUT texture (or keep the current analytic approximation if quality is judged sufficient — worth a visual comparison first).
- Keep the CPU-projected SH for diffuse (no need to also convolve a diffuse cubemap — SH is cheaper and already correct for that term).
Acceptance
- Side-by-side comparison against the current equirect-mip approximation on the Bistro exterior HDRI, confirming visibly improved reflection quality (sharper at low roughness, correctly shaped lobes at mid roughness) with no visible pole artifacts.
- No change to the
EnvironmentComponent/scene-facing API — this only swaps the internal specular-sampling implementation.
Follow-up from #135 (closed), under the Bistro milestone (epic #132).