Skip to content

HSV filter layer + destructive action#69

Merged
TheTechromancer merged 3 commits into
devfrom
hsv-layer
Jul 8, 2026
Merged

HSV filter layer + destructive action#69
TheTechromancer merged 3 commits into
devfrom
hsv-layer

Conversation

@TheTechromancer

Copy link
Copy Markdown
Member
image

HSV/HSL/HSY adjustment filter + destructive-apply parity for all filters

Adds a Hue/Saturation adjustment filter (HSV, HSL, HSY luma-weighted, plus Colorize) and back-fills destructive apply for every parametric filter (Curves, Levels, HSV) through one generic, selection-aware path.

Engine / GPU (Rust)

  • set_filter_params handler (engine/layers.rs) mirroring set_void_params, wiring the previously-dangling updateFilterParams call. add_filter now coerces params against the filter's schema instead of &[].
  • ParamFilter substrate (gpu/param_filter.rs): the single-pass RGBA8 render half shared by all parametric filters — plain + masked (fs_* / fs_*_masked) pipelines, parameterized on whether the shader binds an aux texture ([src, aux, uniform] for the LUT family vs [src, uniform] for HSV). lut_filter.rs's LutFilter becomes the aux-carrying specialization lut_param_filter; curves.wgsl gains fs_curves_masked. Invert stays on the untouched MaskedFilterPipeline.
  • Generic destructive apply (engine/filters/apply.rs, gpu/compositor.rs): dropped the params.is_empty() guard; apply_filter carries params and filter_node_region builds a real EffectCache via ensure(params, …) instead of EffectCache::empty(), so a destructive curves/levels/hsv honors both its params and the selection shape (in-shader select(orig, filtered, selected)).
  • HSV filter (gpu/filters/hsv.rs, shaders/filters/hsv.wgsl): three colour models + colorize over one shader, packing five params into a 32-byte uniform. Colour-space conversions added to shaders/lib/colorspace.wgsl (HSL and HCY, Rec.601), ported from Krita's KoColorConversions. Deliberate deviation from Krita, documented in-shader: HSY caps chroma to gamut so luma is preserved exactly rather than clamping out-of-gamut RGB post-hoc.
  • Node histogram (request_node_histogram handler, compositor::pump_node_histogram): bins a raster node's own texture so the destructive Levels modal still shows a histogram (there's no filter arm in the tree to intercept).

Frontend

  • FilterParamsEditor.svelte: the param-editing surface (channel selector + Curve/Levels editor + scalar rows) extracted from FilterProperties.svelte, now with enum rows (EnumDropdown, gains a disabled prop) and the colorize-disables-model rule. Embedded by both the layer panel (live, undo-coalesced) and the modal (scratch params).
  • FilterModal.svelte + state/filterModal.svelte.ts: the destructive-apply dialog, seeded from schema defaults, hosting the same editor. The Colors-menu action branches — param-free filters apply immediately, parametric ones open the modal.
  • filterParams.ts gains options, seedScratchParams, filterParamMap, colorizeActive, cloneParamValue.
  • README "Features & Roadmap": Hue/Saturation/Lightness checked off.

Tests

  • HSV GPU (tests/filters.rs): identity is a no-op; red +120° is exact green in HSV/HSL but luma-preserving (not pure green) in HSY; full desaturation is achromatic across models; colorize preserves luma and ignores the model selector.
  • Destructive-apply regression: destructive Curves/Levels/HSV over a rect selection change only the selected region (defends the mask + empty-cache bugs). The invert-on-R8-mask-with-selection shipping guard is unchanged and still green.
  • Frontend (filterParams.test.ts): enum partitions to scalars with options; seedScratchParams deep-clones defaults; colorizeActive reflects the colorize bool.

@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

@TheTechromancer TheTechromancer merged commit 2b64690 into dev Jul 8, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant