简介
进度条 Shader,拥有如下特性:
- 可以控制进度条的颜色和背景颜色,包括透明度控制。
- 可以选择进度条的方向。
- 通过传入进度值来更新进度条。
效果如下:
原理
限定形状
传入带有透明通道的贴图并采样,判断当前 uv 是否为透明像素,是的话就渲染为透明,不是的话就按照相应的规则渲染。
渲染进度条
通过 atan2 函数计算当前 XZ 平面的模型坐标相对于 x 轴的旋转角度。
因为 atan2 函数在 Z 方向上为正的时候,夹角为 0 - 180,为负时夹角为 0 - -180,因此我们在夹角为负的时候加上 360,使其在总体上夹角为 0 - 360 范围。
以上是正方向进度条的调整,如果是负方向的话就在夹角为正的时候减去 360,然后取绝对值。
透明度混合
- 前景色透明度和背景色透明度相加,并限制范围为 0 - 255。
- 判断当前像素属于已经走过的进度条还是没走过的,已走过就取步骤 1 的透明度,否则用背景色透明度。
- 判断当前 uv 是否为透明像素,即限定形状,不透明就用步骤 2 的透明度,否则透明度为 0。
代码
进度条Shader1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| Shader "Unlit/Progress" { Properties { _MainTex ("Texture", 2D) = "white" {} _Progress ("Progress",Range(0,1)) = 0 _BackgroundColor ("BackgroundColor",Color) = (0,0,0,0) _ForegroundColor ("ForegroundColor",Color) = (0,1,0,1) [Toggle(_True)]_Forward("Forward", Int) = 1 } SubShader { Tags { "RenderType"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
LOD 100
Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; };
struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float3 pos: TEXCOORD1; };
sampler2D _MainTex; float4 _MainTex_ST; float _Progress; float4 _BackgroundColor; float4 _ForegroundColor; int _Forward;
v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.pos = v.vertex.xyz; return o; }
fixed4 frag(v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); fixed4 final = fixed4(0, 0, 0, 0);
float angle = atan2(i.pos.z, i.pos.x) * (180 / 3.14159); angle = _Forward == 0 ? (angle < 0 ? angle + 360 : angle) : abs(angle > 0 ? angle - 360 : angle);
const float curAngle = _Progress * 360; final.rgb = curAngle >= angle ? _ForegroundColor.xyz * _ForegroundColor.a + _BackgroundColor.xyz * (1 - _ForegroundColor.a) : _BackgroundColor.xyz;
const float quadFinalAlpha = clamp(0,255,_BackgroundColor.a + _ForegroundColor.a) ; const float semiFinalAlpha = curAngle >= angle ? quadFinalAlpha: _BackgroundColor.a; final.a = step(1 - col.a, 0.5) == 1 ? semiFinalAlpha : 0;
return final; } ENDCG } } }
|
项目工程
更新日志