最近遇到个需求需要将2D图片SpriteRenderer支持类似UGUI的Image Filled填充功能,搜了下百度居然搜不到(=_=),然后就自己研究了下Shader,下边直接上代码
目前只支持水平和垂直方向的fill填充,暂时不需要角度填充,所以这里就懒得加了,后面有机会补上角度填充功能
Shader "Sprite/Filled"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
[HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
[HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
[PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
[PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
_Color ("Tint", Color) = (1,1,1,1)
[Enum(Horizontal, 0, Vertical, 1)]_FillType ("FillType", Float) = 0
_FillAmount ("FillAmount", Range(0,1)) = 1
[Toggle]_FillFlip ("FillFlip", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex SpriteVert
// #pragma fragment SpriteFrag
#pragma fragment Frag
#pragma target 2.0
#pragma multi_compile_instancing
#pragma multi_compile_local _ PIXELSNAP_ON
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
#include "UnitySprites.cginc"
float _FillType;
fixed _FillAmount;
fixed _FillFlip;
fixed4 Frag(v2f IN) : SV_Target
{
fixed4 col = SampleSpriteTexture (IN.texcoord) * IN.color;
//计算fill
float uvValue = lerp(IN.texcoord.x, IN.texcoord.y, sign(saturate(_FillType)));
float fValue1 = lerp(uvValue, _FillAmount, sign(saturate(_FillFlip)));
float fValue2 = lerp(_FillAmount, uvValue, sign(saturate(_FillFlip)));
col.a *= step(fValue1, fValue2);
//end
col.rgb *= col.a;
return col;
}
ENDCG
}
}
}
Inspector面板视图
C#调用
///
/// SetSpriteRendererFill
///
///
/// 0-1
/// 0 or 1 (0:Horizaontal, 1:Vertical)
/// 翻转 0 or 1
public static void SetSpriteRendererFill(GameObject obj, float fillAmount, float fillType = 0, float fillFlip = 0)
{
SpriteRenderer sr = obj.GetComponent();
if (sr == null) return;
Material mat = sr.material;
if (mat == null || mat.name != "SpriteToFilled") return;
fillType = Mathf.Clamp01(fillType);
fillAmount = Mathf.Clamp01(fillAmount);
mat.SetFloat("_FillType", fillType);
mat.SetFloat("_FillAmount", fillAmount);
mat.SetFloat("_FillFlip", fillFlip);
}