Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdd348ac6c3

README.md

contrastAdaptiveSharpen

One compute pass, five taps per pixel, at afterLighting order 510 with its composite at 512 — after the antialiasing resolve at 500, since the resolve softens edges and this is what puts the acuity back.

The kernel

Each pixel is recombined with its four neighbours:

out = ((b + d + f + h) * w + e) / (1 + 4w)

w is negative, which is what steepens the local gradient.

Why w is not a constant

A fixed negative lobe overshoots. Subtracting the neighbourhood from a pixel already near black or white pushes it past the range its neighbours occupy, and that overshoot is the bright fringe an unsharp mask leaves along a hard edge.

So w is scaled by how much headroom the neighbourhood has left:

headroom = min(mn, 2 - mx) / mx
w        = sqrt(headroom) * mix(-0.125, -0.2, sharpness)

mn and mx are the neighbourhood minimum and maximum. The term is near 1 in flat midtones and near 0 at an edge that already spans the range, so texture sharpens hard and hard edges are left nearly alone. The square root widens the useful range — without it the lobe collapses long before the neighbourhood actually runs out of room.

Everything is per channel. A saturated red edge still has headroom in green and blue, and treating the channels together would either clip the red or waste the other two.

Inputs

@scene.color and the sharpen_params buffer packed by @builtin::systems.sharpening.sharpening.