lumen_engine/node/processing/
hue_saturation.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!("hue_saturation.wgsl");
9
10#[derive(Debug, Clone, lumen_macros::Delegate)]
12pub struct HueSaturationParams {
13 #[meta(name = "Hue", step = 1)]
15 pub hue_degrees: f64,
16 #[meta(step = 0.01)]
18 pub saturation: f64,
19 #[meta(step = 0.01)]
21 pub lightness: f64,
22}
23
24impl Default for HueSaturationParams {
25 fn default() -> Self {
26 Self {
27 hue_degrees: 0.0,
28 saturation: 1.0,
29 lightness: 0.0,
30 }
31 }
32}
33
34#[derive(Debug, Clone, lumen_macros::Node)]
36#[node(
37 kind = "hue_saturation",
38 name = "Hue Saturation",
39 category = "processing"
40)]
41pub struct HueSaturation {
42 pub id: NodeId,
43 #[params]
44 pub params: HueSaturationParamsDelegate,
45
46 #[input()]
47 pub source: PortRef,
48}
49
50impl Default for HueSaturation {
51 fn default() -> Self {
52 Self {
53 id: NodeId::new(0),
54 params: HueSaturationParamsDelegate::default(),
55 source: PortRef::empty(),
56 }
57 }
58}
59
60#[derive(Debug, Clone)]
61struct CompiledHueSaturation {
62 node_id: NodeId,
63 params: HueSaturationParamsDelegate,
64 buffer: lumen_gpu::BufferId,
65}
66
67impl GpuCompiledNode for CompiledHueSaturation {
68 fn node_id(&self) -> NodeId {
69 self.node_id
70 }
71
72 fn bind(&self, ctx: &FrameBindContext<'_>, bound: &mut BoundFrame) -> crate::Result<()> {
73 let params = self.params.eval(&NodeParamEvalContext {
74 node_id: self.node_id,
75 expr: &ctx.expr_context(self.node_id, "params"),
76 })?;
77 let gpu_params = compiler::HueSaturationParams {
78 hue_offset: (params.hue_degrees / 360.0) as f32,
79 saturation: params.saturation as f32,
80 lightness: params.lightness as f32,
81 _pad: 0.0,
82 };
83 bound.write_buffer(self.buffer, 0, bytemuck::bytes_of(&gpu_params));
84 Ok(())
85 }
86}
87
88impl GpuCompileNode for HueSaturation {
89 fn compile_gpu(
90 &self,
91 ctx: &mut crate::gpu::CompileContext<'_>,
92 port: &PortRef,
93 ) -> crate::Result<CompiledOutput> {
94 let (source, texture, params) = ctx.compile_unary_filter(
95 self.id,
96 &self.source,
97 port,
98 "hue-saturation",
99 SHADER,
100 std::mem::size_of::<compiler::HueSaturationParams>() as u64,
101 )?;
102 ctx.register_compiled_node(CompiledHueSaturation {
103 node_id: self.id,
104 params: self.params.clone(),
105 buffer: params,
106 });
107 Ok(CompiledOutput::Raster(RasterHandle {
108 texture,
109 domain: source.domain,
110 metadata: source.metadata,
111 }))
112 }
113}