From 5cf8391c5a281e6d6886aa240bfe2cba018fe042 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Sun, 11 Dec 2016 15:52:32 +0100 Subject: [PATCH] replace the glsl snow shader with a more lightweight version. (gpu usage is approximately 25% compared to the original.) --- .../gl_shaders/pipeline_snow.glsl.frag.h | 118 +++++++++--------- menu/drivers_display/menu_display_gl.c | 7 ++ 2 files changed, 68 insertions(+), 57 deletions(-) diff --git a/gfx/drivers/gl_shaders/pipeline_snow.glsl.frag.h b/gfx/drivers/gl_shaders/pipeline_snow.glsl.frag.h index e9f47c4554..2f4d96f0ac 100644 --- a/gfx/drivers/gl_shaders/pipeline_snow.glsl.frag.h +++ b/gfx/drivers/gl_shaders/pipeline_snow.glsl.frag.h @@ -1,65 +1,69 @@ #include "shaders_common.h" -static const char *stock_fragment_xmb_snow = GLSL( - uniform float time; - vec2 res = vec2(1920*3, 1080*3); +static const char* stock_fragment_xmb_snow = GLSL( + uniform float time; + uniform vec2 OutputSize; - // High quality = larger patterns - // quality * 84 is the number of seconds in a loop - float quality = 8.0; + float baseScale = 3.5; // [1.0 .. 10.0] + float density = 0.7; // [0.01 .. 1.0] + float speed = 0.25; // [0.1 .. 1.0] - float Cellular2D(vec2 P) { - // https://github.com/BrianSharpe/Wombat/blob/master/Cellular2D.glsl - vec2 Pi = floor(P); - vec2 Pf = P - Pi; - vec4 Pt = vec4( Pi.xy, Pi.xy + 1.0 ); - Pt = Pt - floor(Pt * ( 1.0 / 71.0 )) * 71.0; - Pt += vec2( 26.0, 161.0 ).xyxy; - Pt *= Pt; - Pt = Pt.xzxz * Pt.yyww; - vec4 hash_x = fract( Pt * ( 1.0 / 951.135664 ) ); - vec4 hash_y = fract( Pt * ( 1.0 / 642.949883 ) ); - hash_x = hash_x * 2.0 - 1.0; - hash_y = hash_y * 2.0 - 1.0; - const float JITTER_WINDOW = 0.25; - hash_x = ( ( hash_x * hash_x * hash_x ) - sign( hash_x ) ) * JITTER_WINDOW + vec4( 0.0, 1.0, 0.0, 1.0 ); - hash_y = ( ( hash_y * hash_y * hash_y ) - sign( hash_y ) ) * JITTER_WINDOW + vec4( 0.0, 0.0, 1.0, 1.0 ); - vec4 dx = Pf.xxxx - hash_x; - vec4 dy = Pf.yyyy - hash_y; - vec4 d = dx * dx + dy * dy; - d.xy = min(d.xy, d.zw); - return min(d.x, d.y) * ( 1.0 / 1.125 ); - } + float rand(vec2 co) + { + return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); + } - float snow(vec2 pos, float time, float scale) { - // add wobble - pos.x += cos(pos.y*4.0 + time*3.14159*2.0 + 1.0/scale)/(8.0/scale); - // add gravity - pos += time*scale*vec2(-0.5, 1.0); - return max( - 1.0 - Cellular2D(mod(pos/scale, scale*quality)*16.0)*1024.0, - 0.0 - ) * (scale*0.5 + 0.5); - } + float dist_func(vec2 distv) + { + float dist = sqrt((distv.x * distv.x) + (distv.y * distv.y)) * (40.0 / baseScale); + dist = clamp(dist, 0.0, 1.0); + return cos(dist * (3.14159265358 * 0.5)) * 0.5; + } - void main( void ) { - float winscale = max(res.x, res.y); - float tim = mod(time/8.0, 84.0*quality); - vec2 pos = gl_FragCoord.xy/winscale; - float a = 0.0; - // Each of these is a layer of snow - // Remove some for better performance - // Changing the scale (3rd value) will mess with the looping - a += snow(pos, tim, 1.0); - a += snow(pos, tim, 0.7); - a += snow(pos, tim, 0.6); - a += snow(pos, tim, 0.5); - a += snow(pos, tim, 0.4); - a += snow(pos, tim, 0.3); - a += snow(pos, tim, 0.25); - a += snow(pos, tim, 0.125); - a = a * min(pos.y*4.0, 1.0); - gl_FragColor = vec4(1.0, 1.0, 1.0, a); - } + float random_dots(vec2 co) + { + float part = 1.0 / 20.0; + vec2 cd = floor(co / part); + float p = rand(cd); + + if (p > 0.005 * (density * 40.0)) + return 0.0; + + vec2 dpos = (vec2(fract(p * 2.0) , p) + vec2(2.0, 2.0)) * 0.25; + + vec2 cellpos = fract(co / part); + vec2 distv = (cellpos - dpos); + + return dist_func(distv); + } + + float snow(vec2 pos, float time, float scale) + { + // add wobble + pos.x += cos(pos.y * 1.2 + time * 3.14159 * 2.0 + 1.0 / scale) / (8.0 / scale) * 4.0; + // add gravity + pos += time * scale * vec2(-0.5, 1.0) * 4.0; + return random_dots(pos / scale) * (scale * 0.5 + 0.5); + } + + void main(void) + { + float tim = time * 0.4 * speed; + vec2 pos = gl_FragCoord.xy / OutputSize.xx; + float a = 0.0; + // Each of these is a layer of snow + // Remove some for better performance + // Changing the scale (3rd value) will mess with the looping + a += snow(pos, tim, 1.0); + a += snow(pos, tim, 0.7); + a += snow(pos, tim, 0.6); + a += snow(pos, tim, 0.5); + a += snow(pos, tim, 0.4); + a += snow(pos, tim, 0.3); + a += snow(pos, tim, 0.25); + a += snow(pos, tim, 0.125); + a = a * min(pos.y * 4.0, 1.0); + gl_FragColor = vec4(1.0, 1.0, 1.0, a); + } ); diff --git a/menu/drivers_display/menu_display_gl.c b/menu/drivers_display/menu_display_gl.c index 6048a1085c..f1d056862d 100644 --- a/menu/drivers_display/menu_display_gl.c +++ b/menu/drivers_display/menu_display_gl.c @@ -193,6 +193,13 @@ static void menu_display_gl_draw_pipeline(void *data) uniform_param.lookup.ident = "time"; uniform_param.result.f.v0 = t; + video_shader_driver_set_parameter(uniform_param); + + uniform_param.type = UNIFORM_2F; + uniform_param.lookup.ident = "OutputSize"; + uniform_param.result.f.v0 = draw->width; + uniform_param.result.f.v1 = draw->height; + video_shader_driver_set_parameter(uniform_param); } break;