HSV filter layer + destructive action#69
Merged
Merged
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_paramshandler (engine/layers.rs) mirroringset_void_params, wiring the previously-danglingupdateFilterParamscall.add_filternow coerces params against the filter's schema instead of&[].ParamFiltersubstrate (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'sLutFilterbecomes the aux-carrying specializationlut_param_filter;curves.wgslgainsfs_curves_masked. Invert stays on the untouchedMaskedFilterPipeline.engine/filters/apply.rs,gpu/compositor.rs): dropped theparams.is_empty()guard;apply_filtercarriesparamsandfilter_node_regionbuilds a realEffectCacheviaensure(params, …)instead ofEffectCache::empty(), so a destructive curves/levels/hsv honors both its params and the selection shape (in-shaderselect(orig, filtered, selected)).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 toshaders/lib/colorspace.wgsl(HSL and HCY, Rec.601), ported from Krita'sKoColorConversions. 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.request_node_histogramhandler,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 fromFilterProperties.svelte, now with enum rows (EnumDropdown, gains adisabledprop) 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.tsgainsoptions,seedScratchParams,filterParamMap,colorizeActive,cloneParamValue.Tests
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.filterParams.test.ts): enum partitions to scalars with options;seedScratchParamsdeep-clones defaults;colorizeActivereflects the colorize bool.