static GLchar xemu_logo_frag_src[] =
    "#version 330\n"
    "uniform sampler2D tex;\n"
    "uniform vec4 in_ColorPrimary;\n"
    "uniform vec4 in_ColorFill;\n"
    "uniform float scale;\n"
    "uniform float iTime;\n"
    "out vec4 out_Color;\n"
    "\n"
    "float pxRange           = 6.0;\n"
    "vec4 fgColor            = in_ColorPrimary;\n"
    "vec4 bgColor            = in_ColorFill;\n"
    "const vec4 textPos      = vec4(0.01, 0, 0.98, 0.125);\n"
    "const float pi          = 3.14159265359;\n"
    "const float lineWidth   = 0.175;\n"
    "const float duration    = 1.25;\n"
    "const float pause       = 6.;\n"
    "const int numParticles  = 35;\n"
    "const int numSpotlights = 5;\n"
    "\n"
    "// Thanks to: https://www.shadertoy.com/view/Xl2SRR\n"
    "float random(float co)\n"
    "{\n"
    "    return fract(abs(sin(co*12.989)) * 43758.545);\n"
    "}\n"
    "\n"
    "float median(float r, float g, float b)\n"
    "{\n"
    "    return max(min(r, g), min(max(r, g), b));\n"
    "}\n"
    "\n"
    "// Thanks to: https://www.iquilezles.org/www/articles/functions/functions.htm\n"
    "float quaImpulse( float k, float x )\n"
    "{\n"
    "    return 2.0*sqrt(k)*x/(1.0+k*x*x);\n"
    "}\n"
    "\n"
    "float getCurrentTime()\n"
    "{\n"
    "    return mod(iTime, duration+pause)/duration;\n"
    "}\n"
    "\n"
    "float getBox(vec2 uv, float x, float width)\n"
    "{\n"
    "    float lhs = sign(clamp(x - uv.x,         0., 1.));\n"
    "    float rhs = sign(clamp(x - uv.x + width, 0., 1.));\n"
    "    return rhs-lhs;\n"
    "}\n"
    "\n"
    "float getSweepingLinePos()\n"
    "{\n"
    "    return getCurrentTime()-lineWidth+textPos.x;\n"
    "}\n"
    "\n"
    "float getSweepingLine(vec2 uv)\n"
    "{\n"
    "    return getBox(uv, getSweepingLinePos(), lineWidth);\n"
    "}\n"
    "\n"
    "float getGradients(vec2 uv)\n"
    "{\n"
    "    float t = getCurrentTime();\n"
    "    float l_s = abs(cos(t*pi*2.));\n"
    "    float pos = t - uv.x + textPos.x;\n"
    "    float left = l_s*smoothstep(0., 1., 0.5-abs(pos - lineWidth)*(20.+80.*(1.-l_s)));\n"
    "    float r_s = abs(sin(t*pi*2.));\n"
    "    float right = r_s*smoothstep(0., 1., 0.5-abs(pos)*(20.+80.*(1.-r_s)));\n"
    "    float gradient_y = smoothstep(0.55, 1., 1.-abs(0.5-uv.y));\n"
    "    return (left + right) * gradient_y;\n"
    "}\n"
    "\n"
    "vec2 getSpotlightPos(int i)\n"
    "{\n"
    "    float t = getCurrentTime();\n"
    "    vec2 initialPos = textPos.zw*vec2(\n"
    "        float(i)/float(numSpotlights-1), // Even\n"
    "        sign(random(float(i+62)) - 0.6)*2.); // Top biased\n"
    "\n"
    "    vec2 velocity;\n"
    "    velocity.x = sign(random(float(i+63)) - 0.5)*0.7*(0.3+0.6*random(float(i+100)));\n"
    "    velocity.y = -sign(initialPos.y)*0.8*(0.1+0.9*random(float(i+62)));\n"
    "    return initialPos + velocity * t + vec2(textPos.x, 0.5); // Offset to center\n"
    "}\n"
    "\n"
    "float getSpotlights(vec2 uv)\n"
    "{\n"
    "    float t = getCurrentTime();\n"
    "    float right = smoothstep(0.3, 0.7, 0.8-8.*abs(t - uv.x + textPos.x + 0.05));\n"
    "\n"
    "    // Compute contribution from all spotlights to this frag\n"
    "    float c = 0.;\n"
    "    for (int j = 0; j < numSpotlights; j++) {\n"
    "        vec2 pos = getSpotlightPos(j);\n"
    "        float d = distance(uv, pos);\n"
    "        c += (1.-smoothstep(0.04, 0.07835, d));\n"
    "    }\n"
    "\n"
    "    return 0.6*right + 0.4*c;\n"
    "}\n"
    "\n"
    "// Note: Does not include offset, added in getParticlePosition\n"
    "vec2 getParticleInitialPosition(int i)\n"
    "{\n"
    "    return textPos.zw*vec2(\n"
    "        float(i)/float(numParticles-1), // Even\n"
    "        sign(random(float(i)) - 0.2)); // Top biased\n"
    "}\n"
    "\n"
    "float prob(float p, int i)\n"
    "{\n"
    "    return sign(clamp(random(float(i*30))-(1.-p), 0., 1.));\n"
    "}\n"
    "\n"
    "float getParticleLifespan(int i)\n"
    "{\n"
    "    return 1. + 1.25*exp(-10.*random(float(i*30))) + 0.5*prob(0.3, i);\n"
    "}\n"
    "\n"
    "float getParticleTime(int i)\n"
    "{\n"
    "    return getCurrentTime()-getParticleInitialPosition(i).x;\n"
    "}\n"
    "\n"
    "float getParticleAlive(int i)\n"
    "{\n"
    "  return clamp(sign(getParticleTime(i)), 0., 1.);\n"
    "}\n"
    "\n"
    "float getParticleIntensity(int i)\n"
    "{\n"
    "    return getParticleAlive(i)*clamp(getParticleLifespan(i)-getParticleTime(i), 0., 1.);\n"
    "}\n"
    "\n"
    "vec2 getParticlePosition(int i)\n"
    "{\n"
    "    float pt = getParticleTime(i);\n"
    "    float impulse = quaImpulse(20., pt*0.25+0.05+0.4*random(float(i+30)));\n"
    "    vec2 initialPos = getParticleInitialPosition(i);\n"
    "    vec2 velocity;\n"
    "    // Move mostly right, sometimes left\n"
    "    velocity.x = 0.4*impulse*sign(random(float(i+66)) - 0.1)*(0.3 + 0.6*random(float(i + 100)));\n"
    "    // Move vertically in whatever direction particle spawned in\n"
    "    velocity.y = 0.8*impulse*sign(initialPos.y)*(0.1 + 0.9*random(float(i + 62)));\n"
    "    return initialPos + getParticleAlive(i) * velocity * pt + vec2(textPos.x, 0.5); // Offset to center\n"
    "}\n"
    "\n"
    "float getParticles(vec2 uv)\n"
    "{\n"
    "    // Compute contribution from all particles to this frag\n"
    "    float c = 0.;\n"
    "    for (int j = 0; j < numParticles; j++) {\n"
    "        vec2 pos = getParticlePosition(j);\n"
    "        float d = distance(uv, pos);\n"
    "        c += (1.-smoothstep(0.004, 0.00835,d))*getParticleIntensity(j);\n"
    "    }\n"
    "\n"
    "    return c;\n"
    "}\n"
    "\n"
    "void main()\n"
    "{\n"
    "    vec2 uv = gl_FragCoord.xy/vec2(512);\n"
    "    float scale = 1.4;\n"
    "    uv -= 0.5 * (1.-1./scale);\n"
    "    uv *= scale;\n"
    "    vec2 pos = uv;\n"
    "\n"
    "    vec3 msd = texture(tex, vec2(pos.x, pos.y)).rgb;\n"
    "    float sd = median(msd.r, msd.g, msd.b);\n"
    "    float screenPxDistance = pxRange*(sd - 0.5);\n"
    "    float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0);\n"
    "    vec4 fill_color = mix(bgColor, fgColor, opacity);\n"
    "    float outline = clamp(screenPxDistance + 1.6, 0., 1.);\n"
    "    outline -= clamp(screenPxDistance - 1.6, 0., 1.);\n"
    "    outline = smoothstep(0.5, 1., outline);\n"
    "\n"
    "    vec4 line_color = mix(bgColor, fgColor, outline);\n"
    "    out_Color = mix(fill_color, line_color, getSweepingLine(uv));\n"
    "    float mask_rhs = clamp(sign(uv.x-lineWidth-getSweepingLinePos()),0.,1.);\n"
    "    out_Color += fill_color*mask_rhs*getSpotlights(uv);\n"
    "    out_Color += mix(vec4(0), fgColor, getParticles(uv));\n"
    "    out_Color += 2.*fgColor*getBox(uv, textPos.x, textPos.z)*getGradients(uv);\n"
    "}\n"
    "\n";
