git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

src/draw/shaders.rs (2.4K)

 1 //! The 2D, glyph and 3D scene shaders, shared by every renderer: one WGSL
 2 //! source each.
 3 //!
 4 //! The Vulkan renderer compiles them to SPIR-V through naga. WebGPU takes WGSL
 5 //! as it is, with one difference: it has no push constants, so the per-batch
 6 //! parameter block (`RRectClip`, [`super::PUSH_CONSTANT_FLOATS`] floats laid
 7 //! out by [`super::batch_push_constants`]) is a uniform there, bound at
 8 //! `@group(1) @binding(0)` with a dynamic offset per batch
 9 //! ([`shader2d_for_webgpu`]).
10 
11 /// The 2D pipeline's shader: geometry, the SDF-lit plates, blur-behind.
12 pub const SHADER2D: &str = include_str!("shader2d.wgsl");
13 
14 /// Text and image quads.
15 pub const GLYPH: &str = include_str!("glyph.wgsl");
16 
17 /// The 3D scene pass's meshes ([`super::scene`]).
18 pub const SCENE3D: &str = include_str!("scene3d.wgsl");
19 
20 /// The 3D scene pass's images: textured quads under the meshes' uniforms.
21 pub const SCENE3D_IMAGE: &str = include_str!("scene3d_image.wgsl");
22 
23 /// The lit, textured mesh path of the scene pass (`draw::lit`).
24 pub const SCENE3D_LIT: &str = include_str!("scene3d_lit.wgsl");
25 
26 /// The path tracer ([`super::rt`]): its shared core, then one trace tier
27 /// after it — the compute BVH traversal, or (Vulkan only) hardware ray
28 /// queries — and the à-trous denoiser that runs over its output.
29 pub const RT_COMMON: &str = include_str!("rt_common.wgsl");
30 pub const RT_BVH: &str = include_str!("rt_bvh.wgsl");
31 pub const RT_QUERY: &str = include_str!("rt_query.wgsl");
32 pub const RT_DENOISE: &str = include_str!("rt_denoise.wgsl");
33 
34 /// The compute tier's tracer: [`RT_COMMON`] with [`RT_BVH`] after it.
35 pub fn rt_bvh_source() -> String {
36     format!("{RT_COMMON}\n{RT_BVH}")
37 }
38 
39 /// The one line that differs between the Vulkan and the WebGPU 2D shader.
40 const PUSH_BLOCK: &str = "var<push_constant> rrect_clip: RRectClip;";
41 const UNIFORM_BLOCK: &str = "@group(1) @binding(0) var<uniform> rrect_clip: RRectClip;";
42 
43 /// Where a batch's block sits in WebGPU's uniform buffer: each batch's
44 /// [`super::PUSH_CONSTANT_FLOATS`] floats at a multiple of this, the
45 /// `minUniformBufferOffsetAlignment` every WebGPU device supports.
46 pub const WEBGPU_BLOCK_STRIDE: usize = 256;
47 
48 /// [`SHADER2D`] for WebGPU: the push-constant block declared as a uniform.
49 pub fn shader2d_for_webgpu() -> String {
50     assert_eq!(SHADER2D.matches(PUSH_BLOCK).count(), 1, "shader2d.wgsl must declare its push block exactly once");
51     SHADER2D.replace(PUSH_BLOCK, UNIFORM_BLOCK)
52 }