6

Unity-2D像素晶格化消融 - 小紫苏

 1 year ago
source link: https://www.cnblogs.com/littleperilla/p/16484623.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

效果展示:

2522637-20220716165337988-490090307.gif

ShaderLab

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

才是可操作属性:

image-20220716151322205

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

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

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

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

2522637-20220716165347939-990415364.gif

使用该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

Life is too short for so much sorrow.
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 小紫苏

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK