graphic design tool
git clone https://git.lucas.co/cce-designer.git
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()))?;