WIP: clarity and texture
Checkpoint committed by the coordinator, not by the authoring agent: the session hit its API limit mid-task and left this work uncommitted. Committed so it survives, NOT because it is finished - expect failing tests and half-applied changes. The agent resumes from here.
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
# A hand-written node. `rust:` names the type in `crate::ops` that implements
|
||||
# `Operation`; its descriptor, its parameters and its passes come from that
|
||||
# type rather than from this file. It appears here anyway because `ops/` is
|
||||
# where the pipeline's order is written down, and an order kept half in YAML
|
||||
# and half in Rust would be worse than either alone.
|
||||
id: clarity
|
||||
order: 120
|
||||
|
||||
attributes: [detail]
|
||||
rust: Clarity
|
||||
|
||||
why_rust: |
|
||||
A neighbourhood operation. Clarity is defined by what the pixels around a
|
||||
pixel are doing, and the schema above describes a function of one colour —
|
||||
`wgsl:` is handed `c` and no coordinate, which is the wall the detail stage
|
||||
exists on the other side of. It declares `Affects::Detail` and returns two
|
||||
`DetailPass`es: a Gaussian of log luminance along each axis, the second of
|
||||
which also applies the mask.
|
||||
|
||||
A kernel is also not four facts. Stretching this schema to express a
|
||||
truncation rule, a soft limit and a midtone taper would produce a worse
|
||||
language than Rust, aimed at one caller.
|
||||
|
||||
placement: |
|
||||
In the detail group, after noise reduction and before sharpening.
|
||||
|
||||
Order inside the group is not arbitrary. Clarity multiplies local contrast,
|
||||
so it multiplies noise with it — running it before noise reduction would ask
|
||||
the denoiser to remove grain that clarity had already amplified into
|
||||
structure. And capture sharpening belongs last, on the picture as it will
|
||||
finally be, so that the acutance a photographer judges at 1:1 is the acutance
|
||||
in the file.
|
||||
|
||||
Before texture, which is a decade finer: coarse before fine, so the fine
|
||||
control's base is computed on the modelling the coarse one has already
|
||||
settled.
|
||||
@@ -0,0 +1,23 @@
|
||||
# A hand-written node — see `clarity.yaml`, whose implementation this shares.
|
||||
id: texture
|
||||
order: 130
|
||||
|
||||
attributes: [detail]
|
||||
rust: Texture
|
||||
|
||||
why_rust: |
|
||||
The same neighbourhood operation as clarity, at a tenth of the scale: one
|
||||
implementation in `src/ops/local_contrast.rs`, parameterised by the band it
|
||||
acts on. Two nodes rather than one node with two sliders because the radius
|
||||
is the *definition* of each control rather than a setting of it, and because
|
||||
a texture at zero must then cost nothing at all — which `is_active()` gives
|
||||
for free and a merged node would have had to hand-write.
|
||||
|
||||
placement: |
|
||||
Immediately after clarity, and for the same reasons: after noise reduction,
|
||||
which must not be handed amplified grain, and before capture sharpening,
|
||||
which belongs last.
|
||||
|
||||
After clarity specifically, so that the fine base is computed on the
|
||||
modelling the coarse control has already settled rather than the other way
|
||||
round.
|
||||
Reference in New Issue
Block a user