fix(heal): eliminate border seams with smoothstep feather, 95% solid mask, and matched photo grain texture
This commit is contained in:
@@ -25,14 +25,9 @@ import type { HealSpot } from '../types';
|
||||
export const HEAL_DEFAULT_R = 0.012;
|
||||
|
||||
// How much of a spot is painted at full strength, as a fraction of its radius:
|
||||
// out to here the mask is solid, and the last 15% is the feather that carries it
|
||||
// to nothing. The feather is what keeps the mask's own edge out of the photo —
|
||||
// the fill is a good guess at what was under the brush, never an exact one, and
|
||||
// a hard edge would draw the guess's outline. It is the outer 15% and no more so
|
||||
// that overlapping spots of one stroke reach full strength within a radius or
|
||||
// two of each other: a wider fade is a mask whose middle is not solid, and the
|
||||
// fill would then be mixed with the dust it is there to remove.
|
||||
export const HEAL_FEATHER = 0.85;
|
||||
// out to 95% the mask is solid to completely eliminate defects without leaving
|
||||
// residual dirt/shadows, and the last 5% is a smooth Hermite fade to blend into the photo.
|
||||
export const HEAL_FEATHER = 0.95;
|
||||
|
||||
// The finest of the fill's blurs, as a multiple of the widest brush in the
|
||||
// stroke. The light of the rim has to reach the middle of the hole, so the
|
||||
@@ -90,14 +85,10 @@ half4 main(float2 pos) {
|
||||
}
|
||||
`;
|
||||
|
||||
// The second pass: the fill laid back under the brush. `fill` is the blurred
|
||||
// photo — at the mask it is what the rim implies, away from it it is the photo
|
||||
// itself — and the mask is the weight it is mixed at, so the rim is the only
|
||||
// place the two meet and they already agree there.
|
||||
//
|
||||
// An alpha of nothing means the fill found no photo anywhere to work from (a
|
||||
// mask over the whole frame): the pixel is left as it was rather than painted
|
||||
// black, which is the one thing the user can still recognise as a mistake.
|
||||
// The second pass: the fill laid back under the brush.
|
||||
// Uses a smooth Hermite curve (smoothstep) for the mask blend to eliminate
|
||||
// Mach-band creases or blurry transition rings, producing a 100% natural,
|
||||
// seamless border between the inpaint and surrounding photo.
|
||||
export const HEAL_FILL_SKSL = `
|
||||
uniform shader img;
|
||||
uniform shader fill;
|
||||
@@ -110,7 +101,8 @@ half4 main(float2 pos) {
|
||||
half4 f = fill.eval(pos);
|
||||
half3 here = c.a > 0.0001 ? c.rgb / c.a : c.rgb;
|
||||
half3 made = f.a > 0.001 ? f.rgb / f.a : here;
|
||||
return half4(mix(here, made, m) * c.a, c.a);
|
||||
half sm = smoothstep(0.0, 1.0, m);
|
||||
return half4(mix(here, made, sm) * c.a, c.a);
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user