vo_opengl: increase 3DLUT accuracy at lower LUT sizes

This code had the exact same texture indexing bug that the original
scaler code had before the introduction of the LUT_POS macro to fix it.

We can re-use this same macro here, and the performance drop is
virtually entirely negligible. The benefit is greatly improved LUT
accuracy as the 3DLUT size decreases - in particular, the old LUT
started introducing more and more black crush the lower your LUT size is
(because the error was essentially an over-contrast bias, with a
magnitude linearly related to the lut size).

The new code improves black stability as the LUT size decreases, and
only at very low values (16 and below) do black levels start noticeably
getting affected (due to crude linearization of the nonlinear response
curve).

The default value of 3dlut-size is definitely generous enough for this
to make no difference out of the box, but it also causes no performance
drop at all on my machine so I see no harm in improving the logic.
Furthermore, this means we could easily decrease the default 3dlut size
in a future commit, perhaps even down to 64x64x64 as a default. (But
more testing is warranted here)
This commit is contained in:
Niklas Haas 2016-07-25 10:18:41 +02:00 committed by wm4
parent dcfde2934d
commit ebe798a333
1 changed files with 8 additions and 1 deletions

View File

@ -187,6 +187,7 @@ struct gl_video {
GLuint lut_3d_texture;
bool use_lut_3d;
int lut_3d_size[3];
GLuint dither_texture;
int dither_size;
@ -641,6 +642,9 @@ static bool gl_video_get_lut3d(struct gl_video *p, enum mp_csp_prim prim,
debug_check_gl(p, "after 3d lut creation");
for (int i = 0; i < 3; i++)
p->lut_3d_size[i] = lut3d->size[i];
talloc_free(lut3d);
return true;
@ -2188,7 +2192,10 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool
if (p->use_lut_3d) {
gl_sc_uniform_sampler(p->sc, "lut_3d", GL_TEXTURE_3D, TEXUNIT_3DLUT);
GLSL(color.rgb = texture3D(lut_3d, color.rgb).rgb;)
GLSL(vec3 cpos;)
for (int i = 0; i < 3; i++)
GLSLF("cpos[%d] = LUT_POS(color[%d], %d.0);\n", i, i, p->lut_3d_size[i]);
GLSL(color.rgb = texture3D(lut_3d, cpos).rgb;)
}
}