mirror of
https://github.com/mpv-player/mpv
synced 2024-12-23 15:22:09 +00:00
vo_opengl: implement naive anti-ringing
This is not quite the same thing as madVR's antiringing algorithm, but it essentially does something similar. Porting madVR's approach to elliptic coordinates will take some amount of thought.
This commit is contained in:
parent
6c250505fe
commit
2d182fdea0
@ -306,9 +306,10 @@ Available video output drivers are:
|
||||
``ewa_lanczos``
|
||||
Elliptic weighted average Lanczos scaling. Also known as Jinc.
|
||||
Relatively slow, but very good quality. The number of taps can
|
||||
be controlled with ``lradius``.
|
||||
be controlled with ``lradius``. Adding extra taps makes the filter
|
||||
sharper but adds more ringing.
|
||||
|
||||
Adding extra taps makes the filter sharper but adds more ringing.
|
||||
This filter supports antiringing (see ``lantiring``).
|
||||
|
||||
``mitchell``
|
||||
Mitchell-Netravali. The ``b`` and ``c`` parameters can be set with
|
||||
@ -337,6 +338,14 @@ Available video output drivers are:
|
||||
ratio, the radius that actually being used might be different
|
||||
(most likely being increased a bit).
|
||||
|
||||
``lantiring=<value>``
|
||||
Set the antiringing strength. This tries to eliminate ringing, but can
|
||||
introduce other artifacts in the process. Must be a float number
|
||||
between 0.0 and 1.0. The default value of 0.0 disables antiringing
|
||||
entirely.
|
||||
|
||||
Note that this currently only affects ``ewa_lanczos``.
|
||||
|
||||
``scaler-resizes-only``
|
||||
Disable the scaler if the video image is not resized. In that case,
|
||||
``bilinear`` is used instead whatever is set with ``lscale``. Bilinear
|
||||
@ -434,10 +443,10 @@ Available video output drivers are:
|
||||
down by more than twice (or other factors, depending on image formats),
|
||||
and ``lscale`` did not use a separable scaler.
|
||||
|
||||
``cparam1``, ``cparam2``, ``cradius``
|
||||
``cparam1``, ``cparam2``, ``cradius``, ``cantiring``
|
||||
Set filter parameters and radius for ``cscale``.
|
||||
|
||||
See ``lparam1``, ``lparam2`` and ``lradius``.
|
||||
See ``lparam1``, ``lparam2``, ``lradius`` and ``lantiring``.
|
||||
|
||||
``fancy-downscaling``
|
||||
When using convolution based filters, extend the filter size
|
||||
|
@ -105,6 +105,7 @@ struct scaler {
|
||||
int index;
|
||||
const char *name;
|
||||
float params[2];
|
||||
float antiring;
|
||||
struct filter_kernel *kernel;
|
||||
GLuint gl_lut;
|
||||
const char *lut_name;
|
||||
@ -367,6 +368,8 @@ const struct m_sub_options gl_video_conf = {
|
||||
OPT_FLOAT("cparam2", scaler_params[1][1], 0),
|
||||
OPT_FLOATRANGE("lradius", scaler_radius[0], 0, 1.0, 16.0),
|
||||
OPT_FLOATRANGE("cradius", scaler_radius[1], 0, 1.0, 16.0),
|
||||
OPT_FLOATRANGE("lantiring", scaler_antiring[0], 0, 0.0, 1.0),
|
||||
OPT_FLOATRANGE("cantiring", scaler_antiring[1], 0, 0.0, 1.0),
|
||||
OPT_FLAG("scaler-resizes-only", scaler_resizes_only, 0),
|
||||
OPT_FLAG("fancy-downscaling", fancy_downscaling, 0),
|
||||
OPT_FLAG("sigmoid-upscaling", sigmoid_upscaling, 0),
|
||||
@ -955,9 +958,9 @@ static void shader_setup_scaler(char **shader, struct scaler *scaler, int pass)
|
||||
char lut_fn[40];
|
||||
if (scaler->kernel->polar) {
|
||||
int radius = (int)scaler->kernel->radius;
|
||||
// SAMPLE_CONVOLUTION_POLAR_R(NAME, R, LUT)
|
||||
APPENDF(shader, "SAMPLE_CONVOLUTION_POLAR_R(%s, %d, %s, WEIGHTS%d)\n",
|
||||
name, radius, lut_tex, unit);
|
||||
// SAMPLE_CONVOLUTION_POLAR_R(NAME, R, LUT, WEIGHTS_FN, ANTIRING)
|
||||
APPENDF(shader, "SAMPLE_CONVOLUTION_POLAR_R(%s, %d, %s, WEIGHTS%d, %f)\n",
|
||||
name, radius, lut_tex, unit, scaler->antiring);
|
||||
|
||||
// Pre-compute unrolled weights matrix
|
||||
APPENDF(shader, "#define WEIGHTS%d(LUT) \\\n ", unit);
|
||||
@ -971,7 +974,12 @@ static void shader_setup_scaler(char **shader, struct scaler *scaler, int pass)
|
||||
|
||||
// Samples outside the radius are unnecessary
|
||||
if (d < radius) {
|
||||
APPENDF(shader, "SAMPLE_POLAR(LUT, %f, %d, %d) \\\n ",
|
||||
APPENDF(shader, "SAMPLE_POLAR_%s(LUT, %f, %d, %d) \\\n ",
|
||||
// The center 4 coefficients are the primary
|
||||
// contributors, used to clamp the result for
|
||||
// anti-ringing
|
||||
(x >= 0 && y >= 0 && x <= 1 && y <= 1)
|
||||
? "PRIMARY" : "HELPER",
|
||||
(double)radius, x, y);
|
||||
}
|
||||
}
|
||||
@ -1316,6 +1324,8 @@ static void init_scaler(struct gl_video *p, struct scaler *scaler)
|
||||
scaler->kernel->params[n] = p->opts.scaler_params[scaler->index][n];
|
||||
}
|
||||
|
||||
scaler->antiring = p->opts.scaler_antiring[scaler->index];
|
||||
|
||||
if (scaler->kernel->radius < 0) {
|
||||
float radius = p->opts.scaler_radius[scaler->index];
|
||||
if (!isnan(radius))
|
||||
|
@ -33,6 +33,7 @@ struct gl_video_opts {
|
||||
char *dscaler;
|
||||
float scaler_params[2][2];
|
||||
float scaler_radius[2];
|
||||
float scaler_antiring[2];
|
||||
int indirect;
|
||||
float gamma;
|
||||
int srgb;
|
||||
|
@ -188,6 +188,7 @@ uniform float dither_quantization;
|
||||
uniform float dither_center;
|
||||
uniform float filter_param1_l;
|
||||
uniform float filter_param1_c;
|
||||
uniform float antiring_factor;
|
||||
uniform vec2 dither_size;
|
||||
|
||||
in vec2 texcoord;
|
||||
@ -298,21 +299,31 @@ float[6] weights6(sampler2D lookup, float f) {
|
||||
return res; \
|
||||
}
|
||||
|
||||
#define SAMPLE_POLAR(LUT, R, X, Y) \
|
||||
#define SAMPLE_POLAR_HELPER(LUT, R, X, Y) \
|
||||
w = texture1D(LUT, length(vec2(X, Y) - fcoord)/R).r; \
|
||||
c = texture(tex, base + pt * vec2(X, Y)); \
|
||||
wsum += w; \
|
||||
res += w * texture(tex, base + pt * vec2(X, Y)); \
|
||||
res += w * c; \
|
||||
|
||||
#define SAMPLE_CONVOLUTION_POLAR_R(NAME, R, LUT, WEIGHTS_FN) \
|
||||
#define SAMPLE_POLAR_PRIMARY(LUT, R, X, Y) \
|
||||
SAMPLE_POLAR_HELPER(LUT, R, X, Y) \
|
||||
lo = min(lo, c); \
|
||||
hi = max(hi, c); \
|
||||
|
||||
#define SAMPLE_CONVOLUTION_POLAR_R(NAME, R, LUT, WEIGHTS_FN, ANTIRING) \
|
||||
vec4 NAME(VIDEO_SAMPLER tex, vec2 texsize, vec2 texcoord) { \
|
||||
vec2 pt = vec2(1.0) / texsize; \
|
||||
vec2 fcoord = fract(texcoord * texsize - vec2(0.5)); \
|
||||
vec2 base = texcoord - fcoord * pt; \
|
||||
vec4 res = vec4(0); \
|
||||
float wsum = 0; \
|
||||
vec4 res = vec4(0.0); \
|
||||
vec4 lo = vec4(1.0); \
|
||||
vec4 hi = vec4(0.0); \
|
||||
float wsum = 0.0; \
|
||||
float w; \
|
||||
vec4 c; \
|
||||
WEIGHTS_FN(LUT); \
|
||||
return res / wsum; \
|
||||
res /= wsum; \
|
||||
return mix(res, clamp(res, lo, hi), ANTIRING); \
|
||||
}
|
||||
|
||||
#ifdef DEF_SCALER0
|
||||
|
Loading…
Reference in New Issue
Block a user