A mask layer shall support selection by luminance range and by colour range, each a band with soft edges over the image's own values.
Why
Every local adjustment in DarkRoom currently starts from a shape — painted (MaskSource::Brush), drawn (Linear, Radial), or found by a model (Regions, Subject, Category). A range starts from a property, which is what makes a local edit blend without halos and what a luminosity mask has always been.
It is also the only route to skin-tone work, and the prerequisite for composing selections at all — a bright sky is a luminance range that excludes the dark and a colour range that excludes the non-blue.
DarkRoom is ahead of the field at finding a selection. It has nothing for describing one.
Acceptance
Two new MaskSource variants storing band bounds and softness — not pixels — so they diff, sync and merge per field the way the geometry sources already do (FR-NC-9).
Rasterised on the device in the existing mask pass. No CPU raster at any resolution, per the promise mask.rs makes about Stroke.
A range mask renders identically at proxy and at export resolution.
Part of the Develop Ergonomics spec (FR-DEV series proposal), 2026-09-05.
A mask layer shall support selection by **luminance range** and by **colour range**, each a band with soft edges over the image's own values.
## Why
Every local adjustment in DarkRoom currently starts from a *shape* — painted (`MaskSource::Brush`), drawn (`Linear`, `Radial`), or found by a model (`Regions`, `Subject`, `Category`). A range starts from a *property*, which is what makes a local edit blend without halos and what a luminosity mask has always been.
It is also the only route to skin-tone work, and the prerequisite for composing selections at all — a bright sky is a luminance range that excludes the dark **and** a colour range that excludes the non-blue.
DarkRoom is ahead of the field at *finding* a selection. It has nothing for *describing* one.
## Acceptance
- [ ] Two new `MaskSource` variants storing band bounds and softness — **not pixels** — so they diff, sync and merge per field the way the geometry sources already do (FR-NC-9).
- [ ] Rasterised on the device in the existing mask pass. No CPU raster at any resolution, per the promise `mask.rs` makes about `Stroke`.
- [ ] A range mask renders identically at proxy and at export resolution.
- [ ] Sidecar round-trip covered by a test.
## Lands in
`core/dr-pipeline/src/mask.rs`, `mask.wgsl`, `ui/dr-ui/src/masks_ui.rs`.
---
Part of the Develop Ergonomics spec (FR-DEV series proposal), 2026-09-05.
Landed in 68ebf5d. MaskSource::Luminance and MaskSource::Colour store bounds and softness, never pixels, and the band is weighed in mask.wgsl from the demosaiced source. Sidecar round-trip covered by range_masks_keep_their_bands and writing_a_range_mask_twice_is_byte_identical in core/dr-pipeline/tests/mask_sidecar.rs.
Landed in 68ebf5d. MaskSource::Luminance and MaskSource::Colour store bounds and softness, never pixels, and the band is weighed in mask.wgsl from the demosaiced source. Sidecar round-trip covered by range_masks_keep_their_bands and writing_a_range_mask_twice_is_byte_identical in core/dr-pipeline/tests/mask_sidecar.rs.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
A mask layer shall support selection by luminance range and by colour range, each a band with soft edges over the image's own values.
Why
Every local adjustment in DarkRoom currently starts from a shape — painted (
MaskSource::Brush), drawn (Linear,Radial), or found by a model (Regions,Subject,Category). A range starts from a property, which is what makes a local edit blend without halos and what a luminosity mask has always been.It is also the only route to skin-tone work, and the prerequisite for composing selections at all — a bright sky is a luminance range that excludes the dark and a colour range that excludes the non-blue.
DarkRoom is ahead of the field at finding a selection. It has nothing for describing one.
Acceptance
MaskSourcevariants storing band bounds and softness — not pixels — so they diff, sync and merge per field the way the geometry sources already do (FR-NC-9).mask.rsmakes aboutStroke.Lands in
core/dr-pipeline/src/mask.rs,mask.wgsl,ui/dr-ui/src/masks_ui.rs.Part of the Develop Ergonomics spec (FR-DEV series proposal), 2026-09-05.
Blocks #9 — composition without ranges to compose is worth considerably less. Build the ranges first, then do #9 once.
Makes #10 worth doing.
Landed in
68ebf5d. MaskSource::Luminance and MaskSource::Colour store bounds and softness, never pixels, and the band is weighed in mask.wgsl from the demosaiced source. Sidecar round-trip covered by range_masks_keep_their_bands and writing_a_range_mask_twice_is_byte_identical in core/dr-pipeline/tests/mask_sidecar.rs.