shaders/sampling: optimize/improve polar anti-ringing
- Aug 07, 2023
-
-
Niklas Haas authored
I have improved the AR kernel by combining a number of techniques: 1. Instead of raising the color value to a large exponent (and then taking the inverse exponent later), we can get away with simply multiplying the large exponent directly into the weight. This is much better for numerical accuracy as it means the error is accounted for in wsum, while the original color is left as-is. 2. Instead of taking pow(color, k), take pow(color+1, k). This keeps numbers within the sane floating point range without substantially altering the result of the powermean calculation. (Thanks to @bjin for this trick!) 3. To prevent issues with all-zero wsum, put a small lower bound on the computed weight. (I have no idea how ww can ever be 0 here, but apparently it can...) 4. Finally, to handle edge case where hi < lo, replace the color value by the average of the two in this case. The combination of the above techniques allows us to raise the kernel exponent to a significantly larger number (k=32 works well, any higher introduces more artefacts due to being too close to a true max() - we want an exponent that preserves a good balance between the weighting kernel and the maximum value), substantially improving quality. The downside is that this technique is also quite a bit lower, as a result of the more involved weight summation and higher exponent requiring more multiplications. See-Also: https://github.com/bjin/mpv-prescalers/issues/57
132a828f -
Niklas Haas authored31eb628d
-
Niklas Haas authored
The new approach of using the main lobe radius works even for stretched kernels, and hence works perfectly when downscaling as well.
2c98669b -
Niklas Haas authored
Left over from a previous version of this code.
1b20a863 -
Niklas Haas authored
Instead of having to calculate a completely separate (gaussian) weight function, a much better approach is to just use the main lobe of the main kernel, a parameter we compute at runtime for optimum effect. This significantly reduces computation time by not needing to bother computing extra gaussian weight, and also actually makes the antiringing kernel *smaller* for typical (jinc-based) functions. Very slightly sharper overall than the previous approach, and produces almost similarly few artifacts, though it still looks considerably more blurry than a sharper (e.g. box) cutoff would. More work needed. Inspired by the AR implementation in ravu/mpv-prescalers' RAVU Zoom. See-Also: https://github.com/bjin/mpv-prescalers/issues/57
7fb12078
-