|
30 | 30 | //! `raster::rasterize_tile` then performs a **front-to-back alpha-blend** with |
31 | 31 | //! early-out at `T < T_SATURATION_EPS = 1e-4`. |
32 | 32 | //! |
33 | | -//! External renderers (CesiumJS, three-gaussian-splatting) often use |
34 | | -//! **back-to-front** (painter's-algorithm) order instead. When two or more |
| 33 | +//! The reference renderers (brush, Inria `diff-gaussian-rasterization`) may |
| 34 | +//! sort **back-to-front** (painter's-algorithm) instead. When two or more |
35 | 35 | //! Gaussians have nearly equal depth, floating-point accumulation order is |
36 | 36 | //! reversed between the two approaches, producing per-pixel colour differences |
37 | 37 | //! of order `O(alpha²)`. For high-opacity scenes this can be several dB of |
38 | 38 | //! PSNR. Any SSIM/PSNR delta unexplained by numerical noise should be |
39 | 39 | //! investigated for sort-order as the primary suspect. |
40 | 40 | //! |
41 | | -//! # Real Cesium / cesium-native FFI — DEFERRED |
| 41 | +//! # Reference renderer — same binary, NO FFI |
42 | 42 | //! |
43 | | -//! Running a real CesiumJS or cesium-native render requires a browser/Node |
44 | | -//! context or C++ FFI. That is out of scope for this crate; the interface |
45 | | -//! below is a placeholder. Do NOT attempt to wire it without a full |
46 | | -//! `unsafe` audit by `sentinel-qa`. |
| 43 | +//! There is **no Cesium/cesium-native FFI** and there never will be. The |
| 44 | +//! oracle's "reference" is one of the existing in-scope 3DGS renderers wired |
| 45 | +//! as an ordinary workspace dependency in the **same binary** (A-to-Z, no |
| 46 | +//! `extern "C"`, no browser/Node, no C++ ABI): |
| 47 | +//! |
| 48 | +//! - **`brush`** (`AdaWorldAPI/brush`, Rust + `wgpu`) — runnable in-binary on |
| 49 | +//! CPU/any-GPU with no CUDA toolchain; the default reference path. |
| 50 | +//! - **Inria `gaussian-splatting`** + **`diff-gaussian-rasterization`** |
| 51 | +//! (`AdaWorldAPI/*`, CUDA) — the ground-truth rasterizer when a CUDA device |
| 52 | +//! is present; same binary, linked as a normal Rust crate, not via FFI. |
| 53 | +//! |
| 54 | +//! All three speak our CAM SoA (`splat3d::gaussian::GaussianBatch`) at the |
| 55 | +//! boundary, so the oracle compares like-for-like: load → render(ours) vs |
| 56 | +//! render(reference) → SSIM/PSNR. None of these is a foreign binary; the |
| 57 | +//! wiring is `[dependencies]` + a direct call, gated by `cfg`/feature, once |
| 58 | +//! `ndarray` is re-enabled in `Cargo.toml`. |
47 | 59 | //! |
48 | 60 | //! # Implementation status |
49 | 61 | //! |
@@ -75,9 +87,10 @@ pub enum OracleError { |
75 | 87 | DimensionMismatch { ref_len: usize, candidate_len: usize }, |
76 | 88 | /// The render pipeline returned an empty framebuffer (width or height = 0). |
77 | 89 | EmptyFramebuffer, |
78 | | - // DEFERRED: CesiumNativeFfi — wiring real cesium-native requires C++ FFI |
79 | | - // and a sentinel-qa unsafe audit; placeholder variant reserved. |
80 | | - // CesiumNativeFfi(String), |
| 90 | + // DEFERRED: ReferenceRender(String) — reserved for failures from the |
| 91 | + // in-binary reference renderer (brush / Inria), wired as a workspace |
| 92 | + // dependency once `ndarray` is re-enabled in Cargo.toml. NOT an FFI path. |
| 93 | + // ReferenceRender(String), |
81 | 94 | } |
82 | 95 |
|
83 | 96 | impl std::fmt::Display for OracleError { |
@@ -156,7 +169,7 @@ impl ParityMetrics { |
156 | 169 | /// ``` |
157 | 170 | pub fn compute(reference: &[f32], candidate: &[f32]) -> Result<Self, OracleError> { |
158 | 171 | let n = reference.len(); |
159 | | - if n == 0 || candidate.len() == 0 { |
| 172 | + if n == 0 || candidate.is_empty() { |
160 | 173 | return Err(OracleError::EmptyFramebuffer); |
161 | 174 | } |
162 | 175 | if n != candidate.len() { |
@@ -319,20 +332,41 @@ impl ParityMetrics { |
319 | 332 | // } |
320 | 333 |
|
321 | 334 | // ───────────────────────────────────────────────────────────────────────────── |
322 | | -// DEFERRED: Real Cesium / cesium-native FFI |
| 335 | +// DEFERRED: in-binary reference renderer (brush / Inria) — NO FFI |
323 | 336 | // ───────────────────────────────────────────────────────────────────────────── |
324 | 337 |
|
325 | | -// DEFERRED: Running a real CesiumJS render requires a browser/Node context |
326 | | -// (Electron or Puppeteer) and is out of scope for this crate. |
| 338 | +// The cross-renderer reference is an existing in-scope 3DGS renderer wired as |
| 339 | +// an ordinary workspace dependency in the SAME binary — no `extern "C"`, no |
| 340 | +// `#[link]`, no browser/Node, no foreign ABI. It consumes the same CAM SoA |
| 341 | +// `GaussianBatch` we feed `splat3d`, renders to the same interleaved-RGB |
| 342 | +// framebuffer layout, and we diff the two with `ParityMetrics::compute`. |
| 343 | +// |
| 344 | +// DEFERRED until `ndarray` (and the chosen reference crate) are re-enabled in |
| 345 | +// Cargo.toml and the module passes Opus + CodeRabbit review: |
327 | 346 | // |
328 | | -// DEFERRED: Running cesium-native requires C++ FFI via `unsafe extern "C"`. |
329 | | -// Placeholder stub — do NOT implement without sentinel-qa unsafe audit: |
| 347 | +// // Default reference: brush (Rust + wgpu, runnable without CUDA). |
| 348 | +// // UNVERIFIED: brush's public render entry point + camera/SoA adapter shape; |
| 349 | +// // confirm against AdaWorldAPI/brush before wiring. |
| 350 | +// fn render_reference_brush( |
| 351 | +// batch: &GaussianBatch, |
| 352 | +// camera: &Camera, |
| 353 | +// background: [f32; 3], |
| 354 | +// ) -> Result<Vec<f32>, OracleError> { |
| 355 | +// // brush::render(...) → Vec<f32> interleaved RGB, len = 3·W·H |
| 356 | +// todo!("wire brush as same-binary workspace dep") |
| 357 | +// } |
330 | 358 | // |
331 | | -// #[link(name = "cesium_native")] |
332 | | -// extern "C" { |
333 | | -// // UNVERIFIED: cesium-native does not expose a stable C ABI as of 2024-Q3. |
334 | | -// // fn cesium_render_ply(path: *const u8, path_len: usize, |
335 | | -// // out_rgb: *mut f32, width: u32, height: u32) -> i32; |
| 359 | +// // Ground truth (when a CUDA device is present): Inria gaussian-splatting / |
| 360 | +// // diff-gaussian-rasterization, linked as a normal Rust crate (NOT FFI), |
| 361 | +// // gated behind a `cuda` cfg/feature. |
| 362 | +// // UNVERIFIED: the Rust-facing entry point exposed by the Inria crates. |
| 363 | +// #[cfg(feature = "cuda")] |
| 364 | +// fn render_reference_inria( |
| 365 | +// batch: &GaussianBatch, |
| 366 | +// camera: &Camera, |
| 367 | +// background: [f32; 3], |
| 368 | +// ) -> Result<Vec<f32>, OracleError> { |
| 369 | +// todo!("wire diff-gaussian-rasterization as same-binary workspace dep") |
336 | 370 | // } |
337 | 371 |
|
338 | 372 | // ───────────────────────────────────────────────────────────────────────────── |
|
0 commit comments