git.lucas.co / cce-designer
graphic design tool
git clone https://git.lucas.co/cce-designer.git

commit29c4d1d77f913b59f3da472f7e7ebe3b9a1fd9ad
parentc1581aad58
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-02 14:47
feat: the traced viewport's backdrop is the Background Color

A camera ray that meets nothing shows the Background Color (cce-ui's
set_rt_background), as the raster pass does, where it showed the path
tracer's studio sky. Bounces still meet the sky, so the lighting is
unchanged. --thumbnail takes the colour from the project's display
block, and keeps the sky for a save without one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 CLAUDE.md        | 7 +++++++
 src/app.rs       | 4 ++++
 src/thumbnail.rs | 9 +++++++++
 3 files changed, 20 insertions(+)

diff --git a/CLAUDE.md b/CLAUDE.md
index d64650a..cfcb046 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -310,6 +310,13 @@ gone from cce-ui with the wgpu path).
   (still named `ocl_error` from the days it held OpenCL's), not fatal.
 - `src/viewport_3d.rs` — app-owned `Viewport3D` widget (camera orbit/zoom, inertial
   scroll, `rt_mode` flag switching the pane to the `cce_ui::vk` compute path tracer).
+  **The traced pane's backdrop is the Background Color** (since
+  2026-10-02, `VkRenderer::set_rt_background`, linear RGB like the raster
+  quad's): a camera ray that meets nothing shows it, where it showed the
+  tracer's studio sky. Only the camera ray — a bounce that leaves the
+  scene still meets the sky, the tracer's one light, so the scene is lit
+  as before. `--thumbnail` takes the colour from the project's display
+  block and keeps the sky for a save without one (the bundled projects).
 - `src/viewer_state.rs` — the **viewer-state framework**: interactive viewport
   tools, generalized out of the curve tool. A viewer state is a mode the
   viewport is in, bound to one node, in which the pointer edits that node
diff --git a/src/app.rs b/src/app.rs
index bf9cbe4..f576e40 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -12516,6 +12516,10 @@ pub(crate) fn geometry_to_spreadsheet_data(geom: &Detail) -> (Vec<String>, Vec<V
                     let aspect = cw as f32 / ch as f32;
                     let (proj, view_mat, model) = self.viewport().get_matrices(aspect, Some(camera_pos), Some(Vec3::new(rx, ry, rz)), Some(pivot));
                     let inv_mvp = (proj * view_mat * model).inverse().to_cols_array_2d();
+                    // Behind the scene, the Background Color, as the raster
+                    // pass draws it (since 2026-10-02; it was the tracer's
+                    // sky). The sky still lights the scene.
+                    renderer.set_rt_background(Some(cce_ui::colors::to_linear_rgb(self.viewport().bg_color)));
                     renderer.stage_rt((sx, sy, cw, ch), cce_ui::vk::RtCamera { inv_mvp });
                 }
             } else if self.viewport_dirty {
diff --git a/src/thumbnail.rs b/src/thumbnail.rs
index 325440f..6597353 100644
--- a/src/thumbnail.rs
+++ b/src/thumbnail.rs
@@ -85,6 +85,15 @@ pub fn run(project: &Path, out: &Path, size: u32, samples: Option<u32>, frame: O
         _ => None,
     };
     off.set_scene_with_image(&tris, &mats, image);
+    // Behind the scene, the Background Color the project was saved with, as
+    // the traced viewport shows it; the sky, which still lights the scene,
+    // for a save without display settings.
+    off.set_background(
+        proj.view_state
+            .display
+            .as_ref()
+            .map(|d| cce_ui::colors::to_linear_rgb(d.viewport.bg_color)),
+    );
     let pixels = off.render(camera, size, size, samples.unwrap_or(SAMPLES));
 
     let file = std::fs::File::create(out).map_err(|e| format!("create {}: {e}", out.display()))?;