GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
feat: per-draw opacity on SceneDraw
A whole-draw alpha multiplier through the scene uniform (straight-alpha
blend, already enabled): 1.0 = today's opaque draws. First consumer is
the designer's Render-node Opacity slider.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/vk/scene.rs | 7 +++++++
src/vk/scene3d.wgsl | 4 +++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/vk/scene.rs b/src/vk/scene.rs
index 542616b..f046acf 100644
--- a/src/vk/scene.rs
+++ b/src/vk/scene.rs
@@ -41,6 +41,9 @@ pub struct SceneDraw {
/// lines inherit the mesh's colors and would otherwise vanish into the
/// identical fill beneath.
pub wire_tint: [f32; 4],
+ /// Whole-draw alpha multiplier (1.0 = opaque). The pass blends with
+ /// straight alpha, so translucent draws show whatever rendered beneath.
+ pub opacity: f32,
}
/// shader_3d.wgsl's uniform block.
@@ -52,6 +55,8 @@ struct SceneUniforms {
window_radius: f32,
corner_shape: f32,
wire_tint: [f32; 4],
+ opacity: f32,
+ _pad: [f32; 3],
}
const UNIFORM_SIZE: vk::DeviceSize = std::mem::size_of::<SceneUniforms>() as vk::DeviceSize;
@@ -686,6 +691,8 @@ impl SceneStage {
window_radius: corner_radius_px,
corner_shape,
wire_tint: draw.wire_tint,
+ opacity: draw.opacity,
+ _pad: [0.0; 3],
};
let offset = (self.uniform_stride as usize) * i;
mapped[offset..offset + UNIFORM_SIZE as usize]
diff --git a/src/vk/scene3d.wgsl b/src/vk/scene3d.wgsl
index 64cbc66..a16bc46 100644
--- a/src/vk/scene3d.wgsl
+++ b/src/vk/scene3d.wgsl
@@ -9,6 +9,8 @@ struct Uniforms {
// colors untouched; a wireframe pass overlaid on its own filled mesh
// sets it so the lines separate from the identical fill beneath.
wire_tint: vec4<f32>,
+ // Whole-draw alpha multiplier (straight-alpha blend): 1 = opaque.
+ opacity: f32,
}
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
@@ -100,5 +102,5 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f {
let d = clamp(dot(n, l) * 0.5 + 0.5, 0.0, 1.0);
rgb = rgb * (0.55 + 0.45 * d);
}
- return vec4f(rgb, cov);
+ return vec4f(rgb, cov * uniforms.opacity);
}