Created
May 29, 2020 02:38
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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