From 97dfb249b2268e79ec1548c49c432220b6f1969e Mon Sep 17 00:00:00 2001 From: Timon Date: Fri, 20 Mar 2026 17:00:13 +0000 Subject: [PATCH 1/3] Fix hide artboard for raster render mode --- editor/src/node_graph_executor.rs | 9 +-------- node-graph/libraries/rendering/src/renderer.rs | 13 ++++++++----- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/editor/src/node_graph_executor.rs b/editor/src/node_graph_executor.rs index aa63da4076..820a643a58 100644 --- a/editor/src/node_graph_executor.rs +++ b/editor/src/node_graph_executor.rs @@ -440,8 +440,6 @@ impl NodeGraphExecutor { file_type, name, size, - #[cfg(feature = "gpu")] - transparent_background, artboard_name, artboard_count, .. @@ -491,12 +489,7 @@ impl NodeGraphExecutor { match file_type { FileType::Png => { - let result = if transparent_background { - image.write_to(&mut cursor, ImageFormat::Png) - } else { - let image: RgbImage = image.convert(); - image.write_to(&mut cursor, ImageFormat::Png) - }; + let result = image.write_to(&mut cursor, ImageFormat::Png); if let Err(err) = result { return Err(format!("Failed to encode PNG: {err}")); } diff --git a/node-graph/libraries/rendering/src/renderer.rs b/node-graph/libraries/rendering/src/renderer.rs index 47f4d295f5..7869cf6880 100644 --- a/node-graph/libraries/rendering/src/renderer.rs +++ b/node-graph/libraries/rendering/src/renderer.rs @@ -522,18 +522,21 @@ impl Render for Artboard { fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext, render_params: &RenderParams) { use vello::peniko; - // Render background - let color = peniko::Color::new([self.background.r(), self.background.g(), self.background.b(), self.background.a()]); let [a, b] = [self.location.as_dvec2(), self.location.as_dvec2() + self.dimensions.as_dvec2()]; let rect = kurbo::Rect::new(a.x.min(b.x), a.y.min(b.y), a.x.max(b.x), a.y.max(b.y)); - scene.push_layer(peniko::Fill::NonZero, peniko::Mix::Normal, 1., kurbo::Affine::new(transform.to_cols_array()), &rect); - scene.fill(peniko::Fill::NonZero, kurbo::Affine::new(transform.to_cols_array()), color, None, &rect); - scene.pop_layer(); + // Render background + if !render_params.hide_artboards { + let color = peniko::Color::new([self.background.r(), self.background.g(), self.background.b(), self.background.a()]); + scene.push_layer(peniko::Fill::NonZero, peniko::Mix::Normal, 1., kurbo::Affine::new(transform.to_cols_array()), &rect); + scene.fill(peniko::Fill::NonZero, kurbo::Affine::new(transform.to_cols_array()), color, None, &rect); + scene.pop_layer(); + } if self.clip { scene.push_clip_layer(peniko::Fill::NonZero, kurbo::Affine::new(transform.to_cols_array()), &rect); } + // Since the content's transform is right multiplied in when rendering the content, we just need to right multiply by the artboard offset here. let child_transform = transform * DAffine2::from_translation(self.location.as_dvec2()); let mut render_params = render_params.clone(); From cf64b80d20b770f4dd9becb008f11ba77e508908 Mon Sep 17 00:00:00 2001 From: Timon Date: Fri, 20 Mar 2026 17:03:43 +0000 Subject: [PATCH 2/3] Desktop: Fix transparent viewport blending --- desktop/src/render/composite_shader.wgsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/desktop/src/render/composite_shader.wgsl b/desktop/src/render/composite_shader.wgsl index b018de12ec..c4aae035f2 100644 --- a/desktop/src/render/composite_shader.wgsl +++ b/desktop/src/render/composite_shader.wgsl @@ -71,6 +71,8 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4 { if (viewport_srgb.a < 0.001) { viewport_srgb = constants.background_color; + } else if (viewport_srgb.a < 0.999) { + viewport_srgb = blend(viewport_srgb, constants.background_color); } if (overlay_srgb.a < 0.001) { From 35dbe3b727e8fb482184e981bcdf58bd46f5a952 Mon Sep 17 00:00:00 2001 From: Timon Date: Fri, 20 Mar 2026 17:08:21 +0000 Subject: [PATCH 3/3] Fix vello render using wrong color space conversion for background --- .../no-std-types/src/color/color_types.rs | 24 +++++++++++++++++++ node-graph/libraries/wgpu-executor/src/lib.rs | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/node-graph/libraries/no-std-types/src/color/color_types.rs b/node-graph/libraries/no-std-types/src/color/color_types.rs index ebb654b3d3..84d414abba 100644 --- a/node-graph/libraries/no-std-types/src/color/color_types.rs +++ b/node-graph/libraries/no-std-types/src/color/color_types.rs @@ -893,6 +893,18 @@ impl Color { [(gamma.red * 255.) as u8, (gamma.green * 255.) as u8, (gamma.blue * 255.) as u8, (gamma.alpha * 255.) as u8] } + /// Return the all components as a u8 slice, first component is red, followed by green, followed by blue, followed by alpha. Use this if the [`Color`] is in gamma space. + /// # Examples + /// ``` + /// use core_types::color::Color; + /// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap(); + /// // TODO: Add test + /// ``` + #[inline(always)] + pub fn to_rgba8(&self) -> [u8; 4] { + [(self.red * 255.) as u8, (self.green * 255.) as u8, (self.blue * 255.) as u8, (self.alpha * 255.) as u8] + } + /// Return the all RGB components as a u8 slice, first component is red, followed by green, followed by blue. Use this if the [`Color`] is in linear space. /// /// # Examples @@ -907,6 +919,18 @@ impl Color { [(gamma.red * 255.) as u8, (gamma.green * 255.) as u8, (gamma.blue * 255.) as u8] } + /// Return the all RGB components as a u8 slice, first component is red, followed by green, followed by blue. Use this if the [`Color`] is in gamma space. + /// # Examples + /// ``` + /// use core_types::color::Color; + /// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap(); + /// // TODO: Add test + /// ``` + #[inline(always)] + pub fn to_rgb8(&self) -> [u8; 3] { + [(self.red * 255.) as u8, (self.green * 255.) as u8, (self.blue * 255.) as u8] + } + // https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/ /// Convert a [Color] to a hue, saturation, lightness and alpha (all between 0 and 1) /// diff --git a/node-graph/libraries/wgpu-executor/src/lib.rs b/node-graph/libraries/wgpu-executor/src/lib.rs index e98869238d..011da195e4 100644 --- a/node-graph/libraries/wgpu-executor/src/lib.rs +++ b/node-graph/libraries/wgpu-executor/src/lib.rs @@ -129,7 +129,7 @@ impl WgpuExecutor { if let Some(target_texture) = output.as_mut() { target_texture.ensure_size(&self.context.device, size); - let [r, g, b, a] = background.unwrap_or(Color::TRANSPARENT).to_rgba8_srgb(); + let [r, g, b, a] = background.unwrap_or(Color::TRANSPARENT).to_rgba8(); let render_params = RenderParams { base_color: vello::peniko::Color::from_rgba8(r, g, b, a), width: size.x,