
struct VsInput
{
  float2 pos       : POSITION;
  float4 box       : TEXCOORD0;
  float4 radii     : TEXCOORD1;
  float4 color     : COLOR0;
  float4 scolor    : COLOR1;
  float4 shadow    : TEXCOORD2;
  float  sblur     : TEXCOORD3;
};

struct VsOutput
{
  float4 pos       : POSITION;
  float3 spos      : TEXCOORD0;
  float4 box       : TEXCOORD1;
  float4 radii     : TEXCOORD2;
  float4 color     : COLOR0;
  float4 scolor    : COLOR1;
  float4 shadow    : TEXCOORD3;
};


float4 tm          : register(c16);


VsOutput vsh(VsInput I)
{
  VsOutput O;
  O.pos=float4(I.pos.xy*tm.xy+tm.zw, 1, 1);
  O.spos.xy=I.pos.xy;
  O.spos.z=I.sblur;
  O.box=I.box;
  O.radii=I.radii*255;
  O.color=I.color;
  O.scolor=I.scolor;
  O.shadow.xyz=(I.shadow.xyz-0.5)*255;
  O.shadow.w=max(0.5, I.shadow.w*255);
  return O;
}


float calcBoxDist(float2 sp, float4 box, float4 radii)
{
  float2 p=sp-box.xy;

  float2 rx=(p.y<0) ? radii.xy : radii.zw;
  float r=(p.x<0) ? rx.x : rx.y;

  float2 dp=abs(p)-box.zw*0.5+r;
  return (dp.x>=0 && dp.y>=0) ? r-length(dp)
    : r-max(dp.x, dp.y);
}


float4 psh(VsOutput I) : COLOR
{
  float sblur=I.spos.z;
  float spread=I.shadow.z;
  float blur=I.shadow.w;

  float d=calcBoxDist(I.spos.xy, I.box, I.radii);
  float sd=calcBoxDist(I.spos.xy,
    I.box+float4(I.shadow.xy, 0, 0), I.radii);

  float a=smoothstep(-blur, blur, d);
  float sa=smoothstep(-sblur, sblur, sd+spread);

  sa=sqrt(sa);
  a=sqrt(a);

  float4 sc=I.scolor*sa;

  return (sblur>=0) ? lerp(sc, I.color, a)
    : (I.color*(1-sc.a) + sc)*a;
}
