littleperilla

效果展示:

ShaderLab

Shader功能:图像变白+根据顶点的y值作透明裁剪;

才是可操作属性:

image-20220716151322205

IsDead: 控制像素变白,片元着色阶段IsDead小于0将颜色改为白色;

Percent: 透明剔除分界线,也是图片展示百分比;在顶点计算阶段,记录Percent - vertex.y值,传入片元着色器,直接裁剪;

Revert:反转percent结果;(粒子显示效果和图片遮挡效果正好相反)

调整shader中Percent得到如下结果:

使用该shader创建两个材质,spriterenderer和ParticalSystemRenderer分别使用,ParticalSystem勾选Revert;

完整shader:

Shader "PixelDisappear"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _IsDead("IsDead",float) = 1
        _Percent("Percent",Range(-8,10))=0
        _Revert("Revert",float) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float3 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _Percent;
            float _IsDead;
            float _Revert;


            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex);
                if(_Revert > 0)
                    o.uv.z = _Percent - v.vertex.y;
                else
                    o.uv.z = -_Percent + v.vertex.y;
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                clip(i.uv.z);
                fixed4 col;
                if(_IsDead < 0)
                    col = float4(1,1,1,1);
                else
                    col = tex2D(_MainTex, i.uv);
                
                return col;
            }
            ENDCG
        }
    }
}

ParticalSystem

基础属性设置:

maxparticle控制最大粒子数量;

stopaction决定粒子非loop结束后是disable还是销毁;

gravitymodifier添加一点重力,负值向上移动粒子;

image-20220716164358386

粒子添加shape组件;

选择SpriteRender,需要晶格化的gameobject赋值给Sprite;

Clip裁剪透明通道;

image-20220716163429687

Emisson组件,选择随时间,或者Burst都可;

粒子数量不能高于MaxParicles的设置(高了也没用);

Noise组件设置固定滚动速度;

Quality选2D;

image-20220716164013821

Renderer组件中,添加上面写好的shader材质;

size设置粒子大小;

使用时,代码控制两个材质的percent属性;

public class Test : MonoBehaviour
{
    public SpriteRenderer SP;
    public ParticleSystem PS;
    private bool isDead;
    private float curTime;
    private float offset;
    private float speed = 6.5f;
    Material  matPS;

    [SerializeField]private float startVal = 10;
    private void Start()
    {
        matPS = PS.GetComponent<Renderer>().sharedMaterial;
        matPS.SetFloat("_Percent", startVal );
        SP.sharedMaterial.SetFloat("_Percent", startVal );
        SP.sharedMaterial.SetFloat("_IsDead",1);
    }
    
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.P))
        {
            isDead = true;
            matPS.SetFloat("_Percent", startVal );
            SP.sharedMaterial.SetFloat("_Percent", startVal );
            matPS.SetFloat("_IsDead",-1);
            var mainModule = PS.main;
            mainModule.loop = true;
            PS.gameObject.SetActive(true);
            offset = 0;
        }

        if (isDead)
        {
            offset += Time.deltaTime * speed;
            matPS.SetFloat("_Percent", startVal - offset);
            SP.sharedMaterial.SetFloat("_Percent", startVal - offset);

            if (matPS.GetFloat("_Percent") < -10)
            {
                isDead = false;
                var mainModule = PS.main;
                mainModule.loop = false;
            }
        }
    }
}

image-20220716165009750

相关文章: