抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

简介

进度条 Shader,拥有如下特性:

  • 可以控制进度条的颜色和背景颜色,包括透明度控制。
  • 可以选择进度条的方向。
  • 通过传入进度值来更新进度条。

效果如下:

原理

限定形状

传入带有透明通道的贴图并采样,判断当前 uv 是否为透明像素,是的话就渲染为透明,不是的话就按照相应的规则渲染。

渲染进度条

通过 atan2 函数计算当前 XZ 平面的模型坐标相对于 x 轴的旋转角度。

因为 atan2 函数在 Z 方向上为正的时候,夹角为 0 - 180,为负时夹角为 0 - -180,因此我们在夹角为负的时候加上 360,使其在总体上夹角为 0 - 360 范围。

以上是正方向进度条的调整,如果是负方向的话就在夹角为正的时候减去 360,然后取绝对值。

透明度混合

  1. 前景色透明度和背景色透明度相加,并限制范围为 0 - 255。
  2. 判断当前像素属于已经走过的进度条还是没走过的,已走过就取步骤 1 的透明度,否则用背景色透明度。
  3. 判断当前 uv 是否为透明像素,即限定形状,不透明就用步骤 2 的透明度,否则透明度为 0。

代码

进度条Shader
1
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
// make fog work
#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
{
//贴图采样 只用贴图的a通道
fixed4 col = tex2D(_MainTex, i.uv);
//计算前景色和背景色的透明度和
fixed4 final = fixed4(0, 0, 0, 0);

//计算原点到坐标点相对于x轴的角度
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
}
}
}

项目工程

更新日志

2024-04-01

  1. 更新基本内容。

评论