Skip to content

Instantly share code, notes, and snippets.

@JibbSmart
Created May 29, 2020 02:38
Show Gist options
  • Save JibbSmart/9b067889281586b8aca35783e40ce897 to your computer and use it in GitHub Desktop.
Save JibbSmart/9b067889281586b8aca35783e40ce897 to your computer and use it in GitHub Desktop.
Inspired by Ben Golus' examples of different ways to draw a circular progress bar, this is conceptually similar to the "Arc Tangent" approach without any trig -- about twice as fast for the same look.
Shader "Unity/GradProgress" {
Properties{
_Frac("Progress Bar Value", Range(0,1)) = 1.0
[NoScaleOffset] _AlphaTex("Alpha", 2D) = "White" {}
_FillColor("Fill Color", Color) = (1,1,1,1)
_BackColor("Back Color", Color) = (0,0,0,1)
[Toggle(NO_ANTI_ALIASING)] _NoAntiAliasing("Disable Anti-Aliasing", Float) = 0.0
}
SubShader{
Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" "DisableBatching" = "True"}
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature NO_ANTI_ALIASING
#include "UnityCG.cginc"
// Direct3D compiled stats:
// vertex shader:
// 14 math, but all the new stuff should be done on CPU and passed in. I just put them here for plug-and-play with original.
// fragment shader:
// 13 math, 1 texture w/o anti-aliasing
// 19 math, 1 texture w/ anti-aliasing
half _Frac;
fixed4 _FillColor;
fixed4 _BackColor;
sampler2D _AlphaTex;
struct v2f {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float grad : TEXCOORD1;
float halfFilled : TEXCOORD2;
};
v2f vert(appdata_img v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = v.texcoord.xy;
o.grad = -1.0 / tan(_Frac * UNITY_PI * 2.0);
o.halfFilled = 0.0;
if (_Frac >= 1.0)
{
o.halfFilled = 2.0;
}
else if (_Frac >= 0.5)
{
o.halfFilled = 1.0;
}
else if (_Frac <= 0.0)
{
o.halfFilled = -1.0;
}
return o;
}
fixed4 frag(v2f i) : SV_Target
{
half2 xy = i.uv.xy * 2.0 - 1.0;
half grad = -xy.y / xy.x;
float side = xy.x >= 0.0 ? 0.0 : 1.0;
#if defined(NO_ANTI_ALIASING)
// ternary to pick between fill and background colors
fixed4 col = _FillColor;
if (side == i.halfFilled)
{
col = i.grad > grad ? _FillColor : _BackColor;
}
else
{
col = side > i.halfFilled ? _BackColor : _FillColor;
}
#else
// lerp between colors
fixed4 col = _BackColor;
// screen space derivatives scaled to 1.5 for the smoothstep
half gradientDeriv = clamp(fwidth(grad) * 1.5, -10.0, 10.0);
if (side == i.halfFilled)
{
// smoothstep for a smooth but sharp edge on the progress bar
half barProgress = smoothstep(i.grad, i.grad + gradientDeriv, grad);
col = lerp(_FillColor, _BackColor, barProgress);
}
else
{
col = side > i.halfFilled ? _BackColor : _FillColor;
}
#endif
fixed alpha = tex2D(_AlphaTex, i.uv.xy).a;
col.a *= alpha;
return col;
}
ENDCG
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment