feat/ibl-image-based-lighting #92

Merged
akadmin merged 6 commits from feat/ibl-image-based-lighting into main 2026-06-29 08:00:21 +00:00
Owner

closes #18

closes #18
Implements the split-sum IBL approximation (Brian Karis 2013) with CPU-side
precomputation at environment-load time: irradiance cubemap (32×32, diffuse),
prefiltered environment cubemap (128×128 × 5 mip levels, specular), and a
BRDF integration LUT (512×512). All three artefacts are uploaded as half-float
Vulkan images (R16G16B16A16_SFLOAT / R16G16_SFLOAT).

Fragment shader replaces the constant 0.03 ambient term with the full
diffuse+specular IBL split-sum. A depth-test-disabled skybox pipeline renders
the prefiltered environment map as a fullscreen background. File → Load
Environment... opens a native file dialog for .hdr equirectangular maps.

Adds mat4_inverse (cofactor/Cramer) to math.rs; enables the `hdr` feature on
the existing `image` crate dependency. ADR-0015 documents the design decision.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Set ImageAspects::COLOR + explicit mip/layer range in upload_cubemap_f16's
  ImageViewCreateInfo; ImageView::new with custom info doesn't auto-derive
  aspects (unlike new_default), causing a Vulkan validation panic at startup.
- Replace manual bit-swap with bits.rotate_right(16) in radical_inverse_vdc
  (clippy::manual_rotate).
- Remove stale empty doc-comment line before mat4_inverse in math.rs
  (clippy::empty_line_after_doc_comments).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ImageView::new with custom ImageViewCreateInfo leaves format as UNDEFINED
by default, causing VUID-VkImageViewCreateInfo-None-02273 (format features
empty). Setting format: IBL_FORMAT explicitly matches the image's creation
format and satisfies the validation layer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A 1×1 image supports at most 1 mip level (floor(log2(1))+1 = 1). The default
placeholder prefiltered cubemap was incorrectly allocated with 5 mip levels at
base_size=1, violating VUID-VkImageCreateInfo-mipLevels-00958. The 1-mip
default is sufficient as a placeholder until a real HDR environment is loaded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both File → Load Environment... and File → Load glTF... now run the heavy
work on a background thread, keeping the UI responsive during load. A centered
progress window appears automatically while a task is in flight and disappears
when it completes.

- BackgroundTask / BackgroundTaskResult added to SharedState (app.rs):
  contains a label, Arc<Mutex<f32>> progress, and an mpsc Receiver.
- precompute_ibl gains an `on_progress: impl Fn(f32)` callback parameter;
  progress is reported per irradiance face (0→10%), per prefiltered mip
  (10→50%), and per 16 BRDF rows (50→100%).
- load_environment_action: opens file dialog on main thread, then spawns a
  thread to image::open + precompute_ibl; sends BackgroundTaskResult::Ibl.
- load_gltf_action: opens file dialog on main thread, then spawns a thread
  to call load_gltf; sends BackgroundTaskResult::Gltf. Asset registration
  and command execution happen on the main thread after receipt.
- poll_background_task runs in EditorLayer::on_update each frame via
  try_recv; when the result arrives it is processed and background_task
  is cleared.
- UiPresenter renders a centred frameless egui Window with a ProgressBar
  whenever SharedState::background_task is Some.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs(roadmap): mark PBR, shadow mapping, and IBL as complete
All checks were successful
CI / build (pull_request) Successful in 3m2s
13922340ee
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
akadmin deleted branch feat/ibl-image-based-lighting 2026-06-29 08:00:21 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
akadmin/NemesisEngine!92
No description provided.