diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2020-11-27 15:02:58 +0000 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2020-11-27 15:02:58 +0000 |
commit | b59b60502122b505d20e91ed4dbddcee3abc9ce5 (patch) | |
tree | a4251571a21ee1c84a20feaf1bcc703de19e1e67 | |
parent | f08f0548da7fda905e9288343424df4ddd6221d5 (diff) |
evas gl - experiment with dithered gl rendering
this adds a dither func (4x4 dither matrix) to experiment with higher
quality rendering in gl - this assumes you have a normal 8bit per
channel buffer for now (99% of people) and will approximate values in
between the 256 steps 8 bits provides by using the dither matrix based
on gl_FragCoord position. it's just a flag in the shader flags for now
so can be turned on/off in code. this definitely makes blurs look much
better... everything else seems basicall the same. let's see how this
goes.
@feat
4 files changed, 113 insertions, 9 deletions
diff --git a/src/modules/evas/engines/gl_common/evas_gl_shader.c b/src/modules/evas/engines/gl_common/evas_gl_shader.c index 99b104f651..2f1388056d 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_shader.c +++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c | |||
@@ -13,9 +13,9 @@ | |||
13 | #define I(p) ((int)(intptr_t)p) | 13 | #define I(p) ((int)(intptr_t)p) |
14 | 14 | ||
15 | #ifdef WORDS_BIGENDIAN | 15 | #ifdef WORDS_BIGENDIAN |
16 | # define BASEFLAG SHADER_FLAG_BIGENDIAN | 16 | # define BASEFLAG SHADER_FLAG_DITHER | SHADER_FLAG_BIGENDIAN |
17 | #else | 17 | #else |
18 | # define BASEFLAG 0 | 18 | # define BASEFLAG SHADER_FLAG_DITHER |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | typedef enum { | 21 | typedef enum { |
@@ -47,8 +47,9 @@ typedef enum { | |||
47 | SHADER_FLAG_FILTER_ALPHA_ONLY = (1 << 25), | 47 | SHADER_FLAG_FILTER_ALPHA_ONLY = (1 << 25), |
48 | SHADER_FLAG_FILTER_GRAYSCALE = (1 << 26), | 48 | SHADER_FLAG_FILTER_GRAYSCALE = (1 << 26), |
49 | SHADER_FLAG_FILTER_INVERSE_COLOR = (1 << 27), | 49 | SHADER_FLAG_FILTER_INVERSE_COLOR = (1 << 27), |
50 | SHADER_FLAG_DITHER = (1 << 28), | ||
50 | } Shader_Flag; | 51 | } Shader_Flag; |
51 | #define SHADER_FLAG_COUNT 28 | 52 | #define SHADER_FLAG_COUNT 29 |
52 | 53 | ||
53 | static const char *_shader_flags[SHADER_FLAG_COUNT] = { | 54 | static const char *_shader_flags[SHADER_FLAG_COUNT] = { |
54 | "TEX", | 55 | "TEX", |
@@ -79,6 +80,7 @@ static const char *_shader_flags[SHADER_FLAG_COUNT] = { | |||
79 | "ALPHA_ONLY", | 80 | "ALPHA_ONLY", |
80 | "FILTER_GRAYSCALE", | 81 | "FILTER_GRAYSCALE", |
81 | "FILTER_INVERSE_COLOR", | 82 | "FILTER_INVERSE_COLOR", |
83 | "DITHER", | ||
82 | }; | 84 | }; |
83 | 85 | ||
84 | static Eina_Bool compiler_released = EINA_FALSE; | 86 | static Eina_Bool compiler_released = EINA_FALSE; |
diff --git a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x index d244b37f08..b534f66c41 100644 --- a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x +++ b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x | |||
@@ -98,6 +98,33 @@ static const char fragment_glsl[] = | |||
98 | "uniform float blur_div;\n" | 98 | "uniform float blur_div;\n" |
99 | "#endif\n" | 99 | "#endif\n" |
100 | "// ----------------------------------------------------------------------------\n" | 100 | "// ----------------------------------------------------------------------------\n" |
101 | "#ifdef SHD_DITHER\n" | ||
102 | "const mat4 dm = mat4(vec4( 0, 8, 2, 10),\n" | ||
103 | " vec4(12, 4, 14, 6),\n" | ||
104 | " vec4( 3, 11, 1, 9),\n" | ||
105 | " vec4(15, 7, 13, 5));\n" | ||
106 | "float dither_closest(vec2 pos, float val)\n" | ||
107 | "{\n" | ||
108 | " float limit = dm[int(pos.x)][int(pos.y)] / 16.0;\n" | ||
109 | " if (val <= limit) return 0.0;\n" | ||
110 | " return 1.0;\n" | ||
111 | "}\n" | ||
112 | "float dither_8bit(vec2 modpos, float val)\n" | ||
113 | "{\n" | ||
114 | " float val_quant = float(floor(val * 255.0)) / 255.0;\n" | ||
115 | " float val_delta = (val - val_quant) / (1.0 / 256.0);\n" | ||
116 | " float val_roundup = dither_closest(modpos, val_delta);\n" | ||
117 | " return val_quant + (val_roundup * (1.0 / 256.0));\n" | ||
118 | "}\n" | ||
119 | "vec4 dither(vec4 col, vec2 pos)\n" | ||
120 | "{\n" | ||
121 | " vec2 modpos = vec2(mod(float(pos.x), 4.0), mod(float(pos.y), 4.0));\n" | ||
122 | " return vec4(dither_8bit(modpos, col.r),\n" | ||
123 | " dither_8bit(modpos, col.g),\n" | ||
124 | " dither_8bit(modpos, col.b),\n" | ||
125 | " dither_8bit(modpos, col.a));\n" | ||
126 | "}\n" | ||
127 | "#endif\n" | ||
101 | "#ifndef SHD_FILTER_BLUR\n" | 128 | "#ifndef SHD_FILTER_BLUR\n" |
102 | "void main()\n" | 129 | "void main()\n" |
103 | "{\n" | 130 | "{\n" |
@@ -220,10 +247,13 @@ static const char fragment_glsl[] = | |||
220 | " c.b = c.r;\n" | 247 | " c.b = c.r;\n" |
221 | "#endif\n" | 248 | "#endif\n" |
222 | "#ifdef SHD_FILTER_INVERSE_COLOR\n" | 249 | "#ifdef SHD_FILTER_INVERSE_COLOR\n" |
223 | " c.rgb = c.a - c.rgb;\n" | 250 | " c.rgb = c.a - c.rgba;\n" |
224 | "#endif\n" | 251 | "#endif\n" |
225 | "#ifndef SHD_FILTER_BLUR\n" | 252 | "#ifndef SHD_FILTER_BLUR\n" |
226 | " gl_FragColor =\n" | 253 | " gl_FragColor =\n" |
254 | "#ifdef SHD_DITHER\n" | ||
255 | " dither(\n" | ||
256 | "#endif\n" | ||
227 | " c\n" | 257 | " c\n" |
228 | "#ifndef SHD_NOMUL\n" | 258 | "#ifndef SHD_NOMUL\n" |
229 | " * col\n" | 259 | " * col\n" |
@@ -234,6 +264,9 @@ static const char fragment_glsl[] = | |||
234 | "#ifdef SHD_FILTER_DISPLACE\n" | 264 | "#ifdef SHD_FILTER_DISPLACE\n" |
235 | " * fa\n" | 265 | " * fa\n" |
236 | "#endif\n" | 266 | "#endif\n" |
267 | "#ifdef SHD_DITHER\n" | ||
268 | " , gl_FragCoord.xy)\n" | ||
269 | "#endif\n" | ||
237 | " ;\n" | 270 | " ;\n" |
238 | "}\n" | 271 | "}\n" |
239 | "#else // SHD_FILTER_BLUR\n" | 272 | "#else // SHD_FILTER_BLUR\n" |
@@ -278,9 +311,25 @@ static const char fragment_glsl[] = | |||
278 | " acc += (px1 + px2) * weight;\n" | 311 | " acc += (px1 + px2) * weight;\n" |
279 | " }\n" | 312 | " }\n" |
280 | "#ifndef SHD_NOMUL\n" | 313 | "#ifndef SHD_NOMUL\n" |
281 | " gl_FragColor = (acc / blur_div) * col;\n" | 314 | " gl_FragColor =\n" |
315 | "#ifdef SHD_DITHER\n" | ||
316 | " dither(\n" | ||
317 | "#endif\n" | ||
318 | " (acc / blur_div) * col, gl_FragCoord.xy\n" | ||
319 | "#ifdef SHD_DITHER\n" | ||
320 | " )\n" | ||
321 | "#endif\n" | ||
322 | " ;\n" | ||
282 | "#else\n" | 323 | "#else\n" |
283 | " gl_FragColor = (acc / blur_div);\n" | 324 | " gl_FragColor =\n" |
325 | "#ifdef SHD_DITHER\n" | ||
326 | " dither(\n" | ||
327 | "#endif\n" | ||
328 | " (acc / blur_div), gl_FragCoord.xy\n" | ||
329 | "#ifdef SHD_DITHER\n" | ||
330 | " )\n" | ||
331 | "#endif\n" | ||
332 | " ;\n" | ||
284 | "#endif\n" | 333 | "#endif\n" |
285 | "}\n" | 334 | "}\n" |
286 | "#endif // SHD_FILTER_BLUR\n"; | 335 | "#endif // SHD_FILTER_BLUR\n"; |
diff --git a/src/modules/evas/engines/gl_common/shader/fragment.glsl b/src/modules/evas/engines/gl_common/shader/fragment.glsl index 09947968e9..b715c8de99 100644 --- a/src/modules/evas/engines/gl_common/shader/fragment.glsl +++ b/src/modules/evas/engines/gl_common/shader/fragment.glsl | |||
@@ -97,6 +97,37 @@ uniform float blur_div; | |||
97 | 97 | ||
98 | // ---------------------------------------------------------------------------- | 98 | // ---------------------------------------------------------------------------- |
99 | 99 | ||
100 | #ifdef SHD_DITHER | ||
101 | const mat4 dm = mat4(vec4( 0, 8, 2, 10), | ||
102 | vec4(12, 4, 14, 6), | ||
103 | vec4( 3, 11, 1, 9), | ||
104 | vec4(15, 7, 13, 5)); | ||
105 | |||
106 | float dither_closest(vec2 pos, float val) | ||
107 | { | ||
108 | float limit = dm[int(pos.x)][int(pos.y)] / 16.0; | ||
109 | if (val <= limit) return 0.0; | ||
110 | return 1.0; | ||
111 | } | ||
112 | |||
113 | float dither_8bit(vec2 modpos, float val) | ||
114 | { | ||
115 | float val_quant = float(floor(val * 255.0)) / 255.0; | ||
116 | float val_delta = (val - val_quant) / (1.0 / 256.0); | ||
117 | float val_roundup = dither_closest(modpos, val_delta); | ||
118 | return val_quant + (val_roundup * (1.0 / 256.0)); | ||
119 | } | ||
120 | |||
121 | vec4 dither(vec4 col, vec2 pos) | ||
122 | { | ||
123 | vec2 modpos = vec2(mod(float(pos.x), 4.0), mod(float(pos.y), 4.0)); | ||
124 | return vec4(dither_8bit(modpos, col.r), | ||
125 | dither_8bit(modpos, col.g), | ||
126 | dither_8bit(modpos, col.b), | ||
127 | dither_8bit(modpos, col.a)); | ||
128 | } | ||
129 | #endif | ||
130 | |||
100 | #ifndef SHD_FILTER_BLUR | 131 | #ifndef SHD_FILTER_BLUR |
101 | void main() | 132 | void main() |
102 | { | 133 | { |
@@ -243,6 +274,9 @@ vec4 fetch_pixel(float ox, float oy) | |||
243 | #ifndef SHD_FILTER_BLUR | 274 | #ifndef SHD_FILTER_BLUR |
244 | 275 | ||
245 | gl_FragColor = | 276 | gl_FragColor = |
277 | #ifdef SHD_DITHER | ||
278 | dither( | ||
279 | #endif | ||
246 | c | 280 | c |
247 | #ifndef SHD_NOMUL | 281 | #ifndef SHD_NOMUL |
248 | * col | 282 | * col |
@@ -253,6 +287,9 @@ vec4 fetch_pixel(float ox, float oy) | |||
253 | #ifdef SHD_FILTER_DISPLACE | 287 | #ifdef SHD_FILTER_DISPLACE |
254 | * fa | 288 | * fa |
255 | #endif | 289 | #endif |
290 | #ifdef SHD_DITHER | ||
291 | , gl_FragCoord.xy) | ||
292 | #endif | ||
256 | ; | 293 | ; |
257 | } | 294 | } |
258 | 295 | ||
@@ -312,9 +349,25 @@ void main() | |||
312 | } | 349 | } |
313 | 350 | ||
314 | #ifndef SHD_NOMUL | 351 | #ifndef SHD_NOMUL |
315 | gl_FragColor = (acc / blur_div) * col; | 352 | gl_FragColor = |
353 | #ifdef SHD_DITHER | ||
354 | dither( | ||
355 | #endif | ||
356 | (acc / blur_div) * col, gl_FragCoord.xy | ||
357 | #ifdef SHD_DITHER | ||
358 | ) | ||
359 | #endif | ||
360 | ; | ||
316 | #else | 361 | #else |
317 | gl_FragColor = (acc / blur_div); | 362 | gl_FragColor = |
363 | #ifdef SHD_DITHER | ||
364 | dither( | ||
365 | #endif | ||
366 | (acc / blur_div), gl_FragCoord.xy | ||
367 | #ifdef SHD_DITHER | ||
368 | ) | ||
369 | #endif | ||
370 | ; | ||
318 | #endif | 371 | #endif |
319 | } | 372 | } |
320 | 373 | ||
diff --git a/src/modules/evas/engines/gl_common/shader/gen_shaders.sh b/src/modules/evas/engines/gl_common/shader/gen_shaders.sh index 7c2fec1e47..c477ee4dbe 100755 --- a/src/modules/evas/engines/gl_common/shader/gen_shaders.sh +++ b/src/modules/evas/engines/gl_common/shader/gen_shaders.sh | |||
@@ -3,7 +3,7 @@ | |||
3 | # This script will generate a C file containing all the shaders used by Evas | 3 | # This script will generate a C file containing all the shaders used by Evas |
4 | 4 | ||
5 | DIR=`dirname $0` | 5 | DIR=`dirname $0` |
6 | cd $DIR/../../../../../ | 6 | #cd $DIR/../../../../../ |
7 | 7 | ||
8 | OUTPUT="$DIR/evas_gl_shaders.x" | 8 | OUTPUT="$DIR/evas_gl_shaders.x" |
9 | 9 | ||