• Unity 2D SpriteRenderer filled Shader实现


    最近遇到个需求需要将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(CustomFillType)]
            _FillType ("FillType", Float) = 0
            _FillAmount ("FillAmount", Range(0,1)) = 1
            _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
            }
        }
    }
    
    • 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

    C#调用

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public enum CustomFillType : byte{
        Horizontal = 1,
        Vertical = 2,
    }
    
    public class SpriteRenderFillManager
    {
    
    
        /// <summary>
        /// SetSpriteRendererFill
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="fillAmount"> 0-1 </param>
        /// <param name="fillType"> 0 or 1 (0:Horizaontal, 1:Vertical) </param>
        /// <param name="fillFlip"> 翻转 0 or 1 </param>
        public static void SetSpriteRendererFill(GameObject obj, float fillAmount, float fillType = 0, float fillFlip = 0)
        {
            SpriteRenderer sr = obj.GetComponent<SpriteRenderer>();
            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);
        }
    
    }
    
    
    • 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
  • 相关阅读:
    FPGA学习笔记(八)同步/异步信号的打拍分析及处理
    ROS2初级知识(7):用rqt_console查看日志logs
    便捷查询中通快递,详细物流信息轻松获取
    Gem5 simpoint 全流程
    LuatOS-SOC接口文档(air780E)--coremark - 跑分
    AI无法提振台积电股价
    索尼 toio™ 应用创意开发征文|探索创新的玩乐世界——索尼 toio™
    Android的FragmentManager介绍以及它管理Fragment的流程
    LeetCode 面试题 04.09. 二叉搜索树序列
    nodejs异常处理
  • 原文地址:https://blog.csdn.net/qq_37352817/article/details/125563489