forked from enlightenment/efl
evas - gl - optimize dither shader - use integer vecs and go to 2x2
a 2x2 matrix visually here is about as good as 4x4. at least in what i see, but on low end gpu's it can halve the cost. in fact i was watching the gpu on my old i5-4200u drop down to 340-410mhz (no dithering is 320-360mhz). i got to 630-660mhz with the original 4x4 code. the 4x4 is still there ifdefed out. perhaps i can bring it back with a high-quality dither option, but 2x3 i think is good enough.
This commit is contained in:
parent
0c2cf7e1bf
commit
e65ff7e1e6
|
@ -99,26 +99,35 @@ static const char fragment_glsl[] =
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
"// ----------------------------------------------------------------------------\n"
|
"// ----------------------------------------------------------------------------\n"
|
||||||
"#ifdef SHD_DITHER\n"
|
"#ifdef SHD_DITHER\n"
|
||||||
"const mat4 dm = mat4(vec4( 0, 8, 2, 10),\n"
|
"#ifdef DM_HIQ\n"
|
||||||
" vec4(12, 4, 14, 6),\n"
|
"#define DMMOD 4.0\n"
|
||||||
" vec4( 3, 11, 1, 9),\n"
|
"#define DMDIV (16.0*256.0)\n"
|
||||||
" vec4(15, 7, 13, 5));\n"
|
"const mat4 dm = mat4(vec4( 0.0/DMDIV, 8.0/DMDIV, 2.0/DMDIV, 10.0/DMDIV),\n"
|
||||||
"float dither_closest(vec2 pos, float val)\n"
|
" vec4(12.0/DMDIV, 4.0/DMDIV, 14.0/DMDIV, 6.0/DMDIV),\n"
|
||||||
|
" vec4( 3.0/DMDIV, 11.0/DMDIV, 1.0/DMDIV, 9.0/DMDIV),\n"
|
||||||
|
" vec4(15.0/DMDIV, 7.0/DMDIV, 13.0/DMDIV, 5.0/DMDIV));\n"
|
||||||
|
"#else\n"
|
||||||
|
"#define DMMOD 2.0\n"
|
||||||
|
"#define DMDIV (4.0*256.0)\n"
|
||||||
|
"const mat2 dm = mat2(vec2( 0.0/DMDIV, 2.0/DMDIV),\n"
|
||||||
|
" vec2( 3.0/DMDIV, 1.0/DMDIV));\n"
|
||||||
|
"#endif\n"
|
||||||
|
"float dither_closest(ivec2 pos, float val)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float limit = dm[int(pos.x)][int(pos.y)] / 16.0;\n"
|
" float limit = dm[pos.x][pos.y];\n"
|
||||||
" if (val <= limit) return 0.0;\n"
|
" if (val <= limit) return 0.0;\n"
|
||||||
" return 1.0;\n"
|
" return (1.0 / 256.0);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"float dither_8bit(vec2 modpos, float val)\n"
|
"float dither_8bit(ivec2 modpos, float val)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" float val_quant = float(floor(val * 255.0)) / 255.0;\n"
|
" float val_quant = float(floor(val * 255.0)) / 255.0;\n"
|
||||||
" float val_delta = (val - val_quant) / (1.0 / 256.0);\n"
|
" float val_delta = val - val_quant;\n"
|
||||||
" float val_roundup = dither_closest(modpos, val_delta);\n"
|
" float val_roundup = dither_closest(modpos, val_delta);\n"
|
||||||
" return val_quant + (val_roundup * (1.0 / 256.0));\n"
|
" return val_quant + val_roundup;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"vec4 dither(vec4 col, vec2 pos)\n"
|
"vec4 dither(vec4 col, vec2 pos)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" vec2 modpos = vec2(mod(float(pos.x), 4.0), mod(float(pos.y), 4.0));\n"
|
" ivec2 modpos = ivec2(int(mod(pos.x, DMMOD)), int(mod(pos.y, DMMOD)));\n"
|
||||||
" return vec4(dither_8bit(modpos, col.r),\n"
|
" return vec4(dither_8bit(modpos, col.r),\n"
|
||||||
" dither_8bit(modpos, col.g),\n"
|
" dither_8bit(modpos, col.g),\n"
|
||||||
" dither_8bit(modpos, col.b),\n"
|
" dither_8bit(modpos, col.b),\n"
|
||||||
|
|
|
@ -98,29 +98,39 @@ uniform float blur_div;
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef SHD_DITHER
|
#ifdef SHD_DITHER
|
||||||
const mat4 dm = mat4(vec4( 0, 8, 2, 10),
|
|
||||||
vec4(12, 4, 14, 6),
|
|
||||||
vec4( 3, 11, 1, 9),
|
|
||||||
vec4(15, 7, 13, 5));
|
|
||||||
|
|
||||||
float dither_closest(vec2 pos, float val)
|
#ifdef DM_HIQ
|
||||||
|
#define DMMOD 4.0
|
||||||
|
#define DMDIV (16.0*256.0)
|
||||||
|
const mat4 dm = mat4(vec4( 0.0/DMDIV, 8.0/DMDIV, 2.0/DMDIV, 10.0/DMDIV),
|
||||||
|
vec4(12.0/DMDIV, 4.0/DMDIV, 14.0/DMDIV, 6.0/DMDIV),
|
||||||
|
vec4( 3.0/DMDIV, 11.0/DMDIV, 1.0/DMDIV, 9.0/DMDIV),
|
||||||
|
vec4(15.0/DMDIV, 7.0/DMDIV, 13.0/DMDIV, 5.0/DMDIV));
|
||||||
|
#else
|
||||||
|
#define DMMOD 2.0
|
||||||
|
#define DMDIV (4.0*256.0)
|
||||||
|
const mat2 dm = mat2(vec2( 0.0/DMDIV, 2.0/DMDIV),
|
||||||
|
vec2( 3.0/DMDIV, 1.0/DMDIV));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float dither_closest(ivec2 pos, float val)
|
||||||
{
|
{
|
||||||
float limit = dm[int(pos.x)][int(pos.y)] / 16.0;
|
float limit = dm[pos.x][pos.y];
|
||||||
if (val <= limit) return 0.0;
|
if (val <= limit) return 0.0;
|
||||||
return 1.0;
|
return (1.0 / 256.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float dither_8bit(vec2 modpos, float val)
|
float dither_8bit(ivec2 modpos, float val)
|
||||||
{
|
{
|
||||||
float val_quant = float(floor(val * 255.0)) / 255.0;
|
float val_quant = float(floor(val * 255.0)) / 255.0;
|
||||||
float val_delta = (val - val_quant) / (1.0 / 256.0);
|
float val_delta = val - val_quant;
|
||||||
float val_roundup = dither_closest(modpos, val_delta);
|
float val_roundup = dither_closest(modpos, val_delta);
|
||||||
return val_quant + (val_roundup * (1.0 / 256.0));
|
return val_quant + val_roundup;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 dither(vec4 col, vec2 pos)
|
vec4 dither(vec4 col, vec2 pos)
|
||||||
{
|
{
|
||||||
vec2 modpos = vec2(mod(float(pos.x), 4.0), mod(float(pos.y), 4.0));
|
ivec2 modpos = ivec2(int(mod(pos.x, DMMOD)), int(mod(pos.y, DMMOD)));
|
||||||
return vec4(dither_8bit(modpos, col.r),
|
return vec4(dither_8bit(modpos, col.r),
|
||||||
dither_8bit(modpos, col.g),
|
dither_8bit(modpos, col.g),
|
||||||
dither_8bit(modpos, col.b),
|
dither_8bit(modpos, col.b),
|
||||||
|
|
Loading…
Reference in New Issue