Skip to content

Instantly share code, notes, and snippets.

@zao
Created April 12, 2013 20:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zao/5374870 to your computer and use it in GitHub Desktop.
Save zao/5374870 to your computer and use it in GitHub Desktop.
Thicker dual-line waveform effect
texture tex : WAVEFORMDATA;
sampler sTex = sampler_state
{
Texture = (tex);
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Clamp;
};
struct VS_IN
{
float2 pos : POSITION;
float2 tc : TEXCOORD0;
};
struct PS_IN
{
float4 pos : SV_POSITION;
float2 tc : TEXCOORD0;
};
float4 backgroundColor : BACKGROUNDCOLOR;
float4 highlightColor : HIGHLIGHTCOLOR;
float4 selectionColor : SELECTIONCOLOR;
float4 textColor : TEXTCOLOR;
float cursorPos : CURSORPOSITION;
bool cursorVisible : CURSORVISIBLE;
float seekPos : SEEKPOSITION;
bool seeking : SEEKING;
float4 replayGain : REPLAYGAIN; // album gain, track gain, album peak, track peak
float2 viewportSize : VIEWPORTSIZE;
bool horizontal : ORIENTATION;
bool flipped : FLIPPED;
bool shadePlayed : SHADEPLAYED;
PS_IN VS( VS_IN input )
{
PS_IN output = (PS_IN)0;
float2 half_pixel = float2(1,-1) / viewportSize;
output.pos = float4(input.pos - half_pixel, 0, 1);
if (horizontal)
{
output.tc = float2((input.tc.x + 1.0) / 2.0, input.tc.y);
}
else
{
output.tc = float2((-input.tc.y + 1.0) / 2.0, input.tc.x);
}
if (flipped)
{
output.tc.x = 1.0 - output.tc.x;
}
output.tc.y *= 1.3;
return output;
}
float4 bar( float pos, float2 tc, float4 fg, float4 bg, float width, bool show )
{
float dist = abs(pos - tc.x);
float4 c = (show && dist < width)
? lerp(fg, bg, smoothstep(0, width, dist))
: bg;
return c;
}
float4 faded_bar( float pos, float2 tc, float4 fg, float4 bg, float width, bool show, float vert_from, float vert_to )
{
float dist = abs(pos - tc.x);
float fluff = smoothstep(vert_from, vert_to, abs(tc.y));
float4 c = show
? lerp(fg, bg, max(fluff, smoothstep(0, width, dist)))
: bg;
return c;
}
float4 played( float pos, float2 tc, float4 fg, float4 bg, float alpha)
{
float4 c = bg;
float2 d = 1 / viewportSize;
if (pos > tc.x)
{
c = lerp(c, fg, saturate(alpha));
}
return c;
}
void adjust_range(inout float4 sample)
{
sample.rgb -= 0.5 * sample.a;
sample.rgb *= 1.0 + sample.a;
}
float sq_dist_point_segment(float2 a, float2 b, float2 c)
{
float2 ab = b - a, ac = c - a, bc = c - b;
float e = dot(ac, ab);
if (e <= 0.0)
{
return dot(ac, ac);
}
float f = dot(ab, ab);
if (e >= f)
{
return dot(bc, bc);
}
return dot(ac, ac) - e * e / f;
}
float4 line_sampled( float2 tc, float4 mmr_left, float4 mmr_mid, float4 mmr_right)
{
float H = viewportSize.y;
adjust_range(mmr_left);
adjust_range(mmr_mid);
adjust_range(mmr_right);
float2 us = float2( 0, tc.y*H);
float2 top_left = float2(-1, mmr_left.y * H);
float2 top_mid = float2( 0, mmr_mid.y * H);
float2 top_right = float2( 1, mmr_right.y * H);
float2 bot_left = float2(-1, mmr_left.x * H);
float2 bot_mid = float2( 0, mmr_mid.x * H);
float2 bot_right = float2( 1, mmr_right.x * H);
float top = min(sq_dist_point_segment(top_left, top_mid, us),
sq_dist_point_segment(top_mid, top_right, us));
float bot = min(sq_dist_point_segment(bot_left, bot_mid, us),
sq_dist_point_segment(bot_mid, bot_right, us));
float4 wave = lerp(textColor, float4(0.0, 0.0, 0.0, 0.0), smoothstep(0, 1, sqrt(min(top, bot))/2));
return saturate(wave);
}
float4 evaluate( float2 tc )
{
float W = viewportSize.x;
// alpha 1 indicates biased texture
float mip_factor = pow(10, -2.9);
float4 aura_left = tex1D(sTex, tc.x - 1/W, mip_factor, mip_factor);
float4 aura_mid = tex1D(sTex, tc.x , mip_factor, mip_factor);
float4 aura_right = tex1D(sTex, tc.x + 1/W, mip_factor, mip_factor);
float4 mmr_left = tex1D(sTex, tc.x - 1/W);
float4 mmr_mid = tex1D(sTex, tc.x);
float4 mmr_right = tex1D(sTex, tc.x + 1/W);
float4 fast = line_sampled(tc, mmr_left, mmr_mid, mmr_right);
float4 slow = line_sampled(tc, aura_left, aura_mid, aura_right);
return saturate(0.3*fast + slow*slow.a);
}
float4 PS( PS_IN input ) : SV_Target
{
float dx, dy;
if (horizontal)
{
dx = 1/viewportSize.x;
dy = 1/viewportSize.y;
}
else
{
dx = 1/viewportSize.y;
dy = 1/viewportSize.x;
}
float seekWidth = 2.5 * dx;
float positionWidth = 2.5 * dx;
float4 c0 = evaluate(input.tc);
c0 = bar(cursorPos, input.tc, selectionColor, c0, positionWidth, cursorVisible);
c0 = bar(seekPos, input.tc, selectionColor, c0, seekWidth, seeking );
if (shadePlayed)
{
c0 = played(cursorPos, input.tc, highlightColor, c0, 0.3);
}
return c0;
}
technique Render9
{
pass
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_a PS();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment