lumen_engine/node/processing/
blur.rs1use crate::node::{NodeId, NodeParamEvalContext, NodeParams, PortRef};
2
3use crate::gpu::{
4 BoundFrame, CompiledOutput, FrameBindContext, GpuCompileNode, GpuCompiledNode, RasterHandle,
5 compiler,
6};
7
8pub(crate) const SHADER: &str = include_str!("blur.wgsl");
9
10#[derive(Debug, Clone, lumen_macros::Delegate)]
11pub struct BlurParams {
12 #[meta(min = 0, step = 0.5)]
14 pub radius: f64,
15}
16
17impl Default for BlurParams {
18 fn default() -> Self {
19 Self { radius: 4.0 }
20 }
21}
22
23#[derive(Debug, Clone, lumen_macros::Node)]
25#[node(kind = "blur", name = "Blur", category = "processing")]
26pub struct Blur {
27 pub id: NodeId,
28 #[params]
29 pub params: BlurParamsDelegate,
30 #[input()]
31 pub source: PortRef,
32}
33
34impl Default for Blur {
35 fn default() -> Self {
36 Self {
37 id: NodeId::new(0),
38 params: BlurParamsDelegate::default(),
39 source: PortRef::empty(),
40 }
41 }
42}
43
44#[derive(Debug, Clone)]
45struct CompiledBlur {
46 node_id: NodeId,
47 params: BlurParamsDelegate,
48 buffer: lumen_gpu::BufferId,
49}
50
51impl GpuCompiledNode for CompiledBlur {
52 fn node_id(&self) -> NodeId {
53 self.node_id
54 }
55
56 fn bind(&self, ctx: &FrameBindContext<'_>, bound: &mut BoundFrame) -> crate::Result<()> {
57 let params = self.params.eval(&NodeParamEvalContext {
58 node_id: self.node_id,
59 expr: &ctx.expr_context(self.node_id, "params"),
60 })?;
61 let radius = params.radius.round().clamp(0.0, 32.0) as u32;
62 let params = compiler::BlurParams {
63 values: [radius, 0, 0, 0],
64 };
65 bound.write_buffer(self.buffer, 0, bytemuck::bytes_of(¶ms));
66 Ok(())
67 }
68}
69
70impl GpuCompileNode for Blur {
71 fn compile_gpu(
72 &self,
73 ctx: &mut crate::gpu::CompileContext<'_>,
74 port: &PortRef,
75 ) -> crate::Result<CompiledOutput> {
76 let (source, texture, params) = ctx.compile_unary_filter(
77 self.id,
78 &self.source,
79 port,
80 "blur",
81 SHADER,
82 std::mem::size_of::<compiler::BlurParams>() as u64,
83 )?;
84 ctx.register_compiled_node(CompiledBlur {
85 node_id: self.id,
86 params: self.params.clone(),
87 buffer: params,
88 });
89 Ok(CompiledOutput::Raster(RasterHandle {
90 texture,
91 domain: source.domain,
92 metadata: source.metadata,
93 }))
94 }
95}