mirror of https://github.com/xemu-project/xemu.git
ui: Add xemu logo fragment shader
This commit is contained in:
parent
c5317dd6d6
commit
9851e1588c
|
@ -0,0 +1 @@
|
|||
xemu-logo-frag.h
|
|
@ -0,0 +1,153 @@
|
|||
#version 330
|
||||
#define msdf tex
|
||||
uniform sampler2D tex;
|
||||
uniform vec4 in_ColorPrimary;
|
||||
uniform vec4 in_ColorSecondary;
|
||||
uniform vec4 in_ColorFill;
|
||||
uniform float scale;
|
||||
uniform float iTime;
|
||||
in vec2 Texcoord;
|
||||
out vec4 out_Color;
|
||||
|
||||
float pxRange = 6.0;
|
||||
vec4 bgColor = in_ColorFill;
|
||||
vec4 fgColor = in_ColorPrimary;
|
||||
vec4 particleColor = in_ColorSecondary;
|
||||
const int numParticles = 40;
|
||||
const float duration = 1.1;
|
||||
const float pause = 5.0;
|
||||
const vec4 textPos = vec4(0.01, 0, 0.98, 0.125);
|
||||
const float lineWidth = 0.15;
|
||||
|
||||
// Thanks to: https://www.shadertoy.com/view/Xl2SRR
|
||||
float random(float co)
|
||||
{
|
||||
return fract(sin(co*12.989) * 43758.545);
|
||||
}
|
||||
|
||||
float median(float r, float g, float b) {
|
||||
return max(min(r, g), min(max(r, g), b));
|
||||
}
|
||||
|
||||
// Thanks to: https://www.iquilezles.org/www/articles/functions/functions.htm
|
||||
float quaImpulse( float k, float x )
|
||||
{
|
||||
return 2.0*sqrt(k)*x/(1.0+k*x*x);
|
||||
}
|
||||
|
||||
float getCurrentTime()
|
||||
{
|
||||
return mod(iTime, duration+pause)/duration;
|
||||
}
|
||||
|
||||
float getBox(vec2 uv, float x, float width)
|
||||
{
|
||||
float rhs = sign(clamp(x-uv.x+width, 0., 1.));
|
||||
float lhs = sign(clamp(x-uv.x, 0., 1.));
|
||||
return rhs-lhs;
|
||||
}
|
||||
|
||||
float getSweepingLinePos()
|
||||
{
|
||||
return getCurrentTime()-lineWidth+textPos.x;
|
||||
}
|
||||
|
||||
float getSweepingLine(vec2 uv)
|
||||
{
|
||||
return getBox(uv, getSweepingLinePos(), lineWidth);
|
||||
}
|
||||
|
||||
float getGradients(vec2 uv)
|
||||
{
|
||||
float t = getCurrentTime();
|
||||
float gw = lineWidth/2.;
|
||||
float left = getBox(uv, getSweepingLinePos() - gw, gw)*smoothstep(0., 1., (gw + lineWidth - (t - uv.x + textPos.x))/lineWidth);
|
||||
float right = getBox(uv, getSweepingLinePos() + lineWidth, gw)*smoothstep(0., 1., (gw + (t - uv.x + textPos.x))/lineWidth);
|
||||
float gradient_y = smoothstep(0.8, 1., 1.-abs(0.5-uv.y));
|
||||
return (left + right) * gradient_y;
|
||||
}
|
||||
|
||||
// Note: Does not include offset, added in getParticlePosition
|
||||
vec2 getParticleInitialPosition(int i)
|
||||
{
|
||||
vec2 pos;
|
||||
pos.x = float(i)/float(numParticles-1); // Even
|
||||
pos.y = sign(random(float(i)) - 0.1); // Top biased
|
||||
return pos*textPos.zw;
|
||||
}
|
||||
|
||||
float getParticleTime(int i)
|
||||
{
|
||||
// Compute based on initial x due to sweeping reveal
|
||||
return getCurrentTime()-getParticleInitialPosition(i).x;
|
||||
}
|
||||
|
||||
float getParticleIntensity(int i)
|
||||
{
|
||||
float lifespan = 1.0 + 0.4*(random(float(i*44))-0.5);
|
||||
float alive = clamp(sign(getParticleTime(i)), 0., 1.);
|
||||
return alive*clamp(lifespan-getParticleTime(i), 0., 1.);
|
||||
}
|
||||
|
||||
vec2 getParticlePosition(int i)
|
||||
{
|
||||
float pt = getParticleTime(i);
|
||||
float alive = clamp(sign(pt), 0., 1.);
|
||||
float falloff = 10.;
|
||||
float impulse = quaImpulse(falloff, pt+0.8)+0.2;
|
||||
vec2 pos = getParticleInitialPosition(i);
|
||||
|
||||
vec2 velocity;
|
||||
// Move mostly right, but sometimes left
|
||||
velocity.x = sign(random(float(i+32*3030))-0.2);
|
||||
velocity.x *= impulse*1.25*(0.00 + random(float(i+62)));
|
||||
// Move vertically in whatever direction we spawned in
|
||||
velocity.y = sign(pos.y);
|
||||
velocity.y *= impulse*1.40*(0.05 + random(float(i+62)));
|
||||
return pos + alive * velocity * pt + vec2(textPos.x, 0.5); // Offset to center
|
||||
}
|
||||
|
||||
float getParticles(vec2 uv)
|
||||
{
|
||||
// Compute contribution from all particles to this frag
|
||||
float c = 0.;
|
||||
for (int j = 0; j < numParticles; j++) {
|
||||
vec2 pos = getParticlePosition(j);
|
||||
float d = distance(uv, pos);
|
||||
c += (1.-smoothstep(0.01, 0.01035,d))*getParticleIntensity(j);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Normalized pixel coordinates (from 0 to 1)
|
||||
vec2 uv = gl_FragCoord.xy/vec2(512);
|
||||
float scale = 1.4;
|
||||
|
||||
// Center when scaling
|
||||
uv -= 0.5 * (1.-1./scale);
|
||||
uv *= scale;
|
||||
vec2 pos = uv;
|
||||
|
||||
// Get signed distance from the input texture
|
||||
// Thanks to https://github.com/Chlumsky/msdfgen
|
||||
vec2 msdfUnit = pxRange/vec2(textureSize(msdf, 0));
|
||||
vec3 s = texture(msdf, pos).rgb;
|
||||
|
||||
// Create an alpha mask for the text
|
||||
float sigDist = median(s.r, s.g, s.b) - 0.5;
|
||||
sigDist *= dot(msdfUnit, 0.5/fwidth(pos));
|
||||
|
||||
float smoothing = 4.-scale;
|
||||
float fill = smoothstep(0.5 - smoothing, 0.5 + smoothing, sigDist);
|
||||
vec4 fill_color = mix(bgColor, fgColor, fill);
|
||||
|
||||
float outline = smoothstep(0.65, 0.80, 1.0-abs(sigDist/15.0-(-0.3333*scale+0.6667)+0.05));
|
||||
vec4 line_color = mix(bgColor, fgColor, outline);
|
||||
|
||||
out_Color = mix(fill_color, line_color, getSweepingLine(uv));
|
||||
out_Color += mix(bgColor, particleColor, getParticles(uv));
|
||||
out_Color += 2.*vec4(1.)*getBox(uv, textPos.x, textPos.z)*getGradients(uv);
|
||||
}
|
Loading…
Reference in New Issue