Skip to content

Rendering quality roadmap: layered PBR and renderer foundations - #147

Draft
proggeramlug wants to merge 386 commits into
mainfrom
codex/rendering-wip-integrated-20260727
Draft

proggeramlug wants to merge 386 commits into
mainfrom
codex/rendering-wip-integrated-20260727

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

Status

Draft cumulative rendering-quality branch. The branch is intentionally kept reviewable, continuously pushed, and regression-gated while the remaining roadmap work is completed. Parent roadmap: #126.

Included so far

Latest qualification

Head 21f73d8 passes every required hosted check:

  • 306 shared unit tests passed (1 ignored), the production negotiated-device integration passed, 44 renderer goldens passed (2 ignored), and 3 render-target tests passed
  • strict formatting/clippy, FFI/schema parity, file ratchets, wasm compile/build, and quality-governance tests pass
  • macOS, Ubuntu Linux, and Windows release builds pass
  • dependent macOS Chrome passes the real WebGPU known-frame/compositor-pixel smoke against the exact Ubuntu-built package
  • production renderer construction passes locally in automatic high-end, forced baseline, and forced modern modes
  • all 20 canonical package/main examples pass Perry code generation locally; their inventory is completeness-checked in PR CI
  • exact Damaged Helmet A/B: SSIM 0.98803, luminance RMSE 0.01653 (pass)
  • ordinary steady-state rendering has no new per-frame pass or CPU work; capability detection/device planning is startup work only

Remaining before ready

This draft does not auto-close remaining roadmap issues; issue checklists are updated only when their evidence is complete.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
Finishing Touches

🧪 Generate unit tests (beta)

  • Create PR with unit tests
  • Commit unit tests in branch codex/rendering-wip-integrated-20260727
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

This was referenced Jul 27, 2026
@proggeramlug

Copy link
Copy Markdown
Contributor Author

Checkpoint pushed: 7962bee adds the qualified bounded rigid-opaque VSM page indirect path; 87b9d2e adds exact image/performance evidence and updates the current VSM contract.

The path remains compatibility-safe for cutout/skinned/dynamic/small/Web/unsupported work and allocates nothing until a page qualifies.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Second #132 checkpoint pushed: c1131d0 adds the deterministic VSM/CSM contact-detail fixture and dependency-free semantic gate; 3050fd7 records exact images, memory, and counterbalanced timings.

The geometric-detail acceptance box on #132 is now checked with automated evidence (50.37x strong-edge retention, 1.619x p99 edge, +0.00756 shadow contrast). The full quick lane passes and this checkpoint changes no production renderer behavior.

Details: #132 (comment)

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Issue #132 capability-fallback checkpoint is complete and pushed.

Code: c34743e
Evidence/docs: d306164

Forced baseline/modern VSM requests now select canonical CSM before shader/resource construction, report the exact reason, and allocate/submit zero VSM work. A 120/120-frame forced-baseline request is byte-identical to its CSM control (SHA-256 596a8b611496b56b9f2e5747f95b706effa2b85e136e84e481afb1d0bc987d6f). The qualified high-tier VSM hash remains unchanged at 81c6d840a275ee4fe3ff9fbeb87a5a1e21b23bb1c087a4e24c024c2f778b0bde.

The full quick lane, supported Web crate check, iOS aarch64, and Android aarch64 all pass. Five counterbalanced performance pairs show a 0.000288 ms median shadow-CPU difference within noise; both lower-tier modes execute the same frame path.

Evidence: https://github.com/Bloom-Engine/engine/blob/d306164/docs/evidence/issue-132-capability-fallback-v1.md

Issue #132 now marks the forced web/mobile/constrained fallback criterion complete.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Issue #132 checkpoint: alpha-tested and skinned VSM caster coverage is now automated and qualified.

  • Implementation: 862981f
  • Evidence/docs: 3015dcb
  • Real oracle: Sponza MASK caster isolated by a no-cast control; animated Fox isolated by an 8-frame same-jitter pose delta in a ground-only ROI.
  • Result: 19,931 alpha-shadow pixels and 4,465 skinned-shadow pixels changed with strong contrast; 4 cutout + 4 skinned VSM draws were observed and all hard page/draw budgets held.
  • Repeat capture stayed within 1/255 with SSIM 1.0.
  • Exact pushed state passed the full quick lane, including FFI, Web/WASM, strict Clippy, 348 shared tests, 59 GPU goldens, 4 render-target tests, 25 quality tests, and 20 examples.

Evidence: https://github.com/Bloom-Engine/engine/blob/3015dcb/docs/evidence/issue-132-caster-coverage-v1.md

…0260727' into codex/issue-149-web-fallback-quality
Retain the governed nine-tap upsample after alternating Metal runs showed the four-fetch reconstruction was neutral. Remove the smallest bloom mip instead, saving two render passes, and expose per-level profiler labels so pass overhead remains attributable.
@proggeramlug

Copy link
Copy Markdown
Contributor Author

Windows RTX 4080 / Vulkan hardware handoff is ready in #153 at exact commit 4508eaff082b849203ac60f9d8f3a327b71d95c9. The pickup ticket contains host prerequisites, pinned Bistro setup, strict command, exit semantics, archive commands, and the required return checklist. The branch now forces Vulkan and hardware GI for the governed class, uses the active Python interpreter and main.exe on Windows, and includes a refreshed Windows Cargo lock.

Found while running tuichess 3D (a three.js game compiled by Perry) on
macOS, iOS, iPadOS and tvOS.

- Camera clip planes: setCameraClipPlanes(near, far). begin_mode_3d used a
  fixed 0.01..1000, which at ~15 units from the camera resolves only about a
  millimetre of depth: surfaces 1 mm apart z-fought (made worse by TAA
  jitter). Changing the planes invalidates TAA history.
- Perry string headers: Perry sets runtime-internal hint bits
  (JSON_ESCAPE_FREE, WTF8_VALIDATED, more in 0.5.1663: 0x1c is common on
  literals). They don't change the payload, so they are no longer treated as
  an ABI mismatch; only HAS_LONE_SURROGATES changes decoding.
- createTextureRgba8: with alpha >= 128, `a << 24` is negative in JS and the
  u32 FFI slot saturated it to 0 (`>>> 0` keeps it unsigned).
- Display scale and safe-area insets (getDisplayScale, getSafeAreaInset):
  iOS reports them every frame from the view's trait collection and
  safeAreaInsets; other platforms report 1 and 0 (display.rs).
- Touch taps: iOS delivers touches on the UI thread, so a whole tap could
  start and end between two begin_frames and be lost; press/release are
  latched until the next frame.
- tvOS: setMenuButtonExits(on) switches whether Menu leaves the app or
  reaches the game, as a game's top level does.
- Jolt build cache: Apple simulators get their own cache (target ABI "sim");
  a shared one handed simulator objects to a device link.
Renderer::new created every pipeline of every feature up front, one after
another: 57 pipelines and 10.8 s on an M1 Max with a cold Metal shader cache
(first launch after install or an OS/driver update), of which a game at the
Medium preset used 16. Path tracing, hardware-RT probes, the GPU-driven
renderer and the rest compiled whether or not they ever ran.

- renderer/lazy_pipeline.rs: LazyRenderPipeline / LazyComputePipeline keep an
  owned copy of the descriptor (modules and layouts are refcounted handles)
  and compile on first Deref. Creation sites change one call; use sites
  deref-coerce. Correctness doesn't depend on any list: whatever a frame
  draws is built on first use.
- Renderer::prewarm_pipelines: when the settings that select pipelines
  change (first frame, a quality preset, a feature toggled at runtime), the
  pipelines those settings use compile on background threads; a draw waits
  only for the one it needs. Conditions measured per preset with a
  pipeline-use trace. No-op on wasm (wgpu objects aren't Send there).
- BLOOM_PIPELINE_LOG=1 prints each compile, its time and whether it ran on a
  prewarm thread or made a frame wait.

Measured (M1 Max, MTL_SHADER_CACHE_SIZE=0 for cold):
  cold initWindow 11.4 s -> 0.5 s, then ~0.9 s in the first 3D frame
  warm initWindow 0.6-0.9 s -> 0.33 s
  tuichess 3D at Medium and High: every pipeline it draws is prewarmed,
  none compiles on the render thread

BRDF LUT at build time: build.rs includes brdf_lut.rs and writes the
256x256 table to OUT_DIR once per build (1.7 s, only when the generator
changes); the renderer embeds it. Computing it at startup took ~0.4 s on an
M1 Max at every launch, more on phones and the single-threaded web build.
A test checks the embedded table against the generator.

Profiler: a label can cover several passes (the bloom mip chain), and on
tile-based GPUs consecutive passes overlap (the next pass's vertex work
starts while the previous pass's fragments run), so summing their intervals
counted the same GPU time several times: bloom read 5.4 ms for 0.8 ms of
work, 49 ms inside a 13 ms frame in a real scene. Per-label GPU time and
the frame totals are now the union of the intervals; CPU frame totals too
(phases nest: queue_submit runs inside render_total).
feat: expand Three.js renderer compatibility
fix: Apple platform and FFI fixes from running a three.js app on Bloom
…0260727' into perf/lazy-pipelines-startup

# Conflicts:
#	native/shared/src/renderer/mod.rs
perf: compile pipelines on first use and prewarm them in parallel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant