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's computeIrradianceSh).
  • Specular: reuse the equirect texture's own auto-generated mip chain (SDL_GenerateMipmapsForGPUTexture), sampled via textureLod keyed 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_CUBE render-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).