Mask裁剪UI粒子特效

核心原理

GPU 每次刷新屏幕时,会重新计算物体上的 Shader 中的顶点着色器和片面着色器,然后输出计算结果并显示到屏幕上。在计算片面着色器时,需要将材质的顶点的世界坐标和 Mask 裁剪区域的边界进行比对,判断该顶点是否在裁剪区域内,如果不是就将该顶点的透明通道设为零。

下面附上Shader代码:
//add 注释中的内容是修改的地方

//Mask裁切UI粒子系统
Shader "Particles/AdditiveMask" {
	Properties {
		_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
		_MainTex ("Particle Texture", 2D) = "white" {}
		_InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
	
		//-------------------add----------------------
		_MinX ("Min X", Float) = -10
		_MaxX ("Max X", Float) = 10
		_MinY ("Min Y", Float) = -10
		_MaxY ("Max Y", Float) = 10
		//-------------------add----------------------
	}
 
	Category {
		Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
		Blend SrcAlpha One
		AlphaTest Greater .01
		ColorMask RGB
		Cull Off Lighting Off ZWrite Off Fog { Color (0,0,0,0) }
	
		SubShader {
			Pass {
		
				CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				#pragma multi_compile_particles
 
				#include "UnityCG.cginc"
 
				sampler2D _MainTex;
				fixed4 _TintColor;
				//-------------------add----------------------
				float _MinX;
				float _MaxX;
				float _MinY;
				float _MaxY;
				//-------------------add----------------------
			
				struct appdata_t {
					float4 vertex : POSITION;
					fixed4 color : COLOR;
					float2 texcoord : TEXCOORD0;
				};
 
				struct v2f {
					float4 vertex : SV_POSITION;
					fixed4 color : COLOR;
					float2 texcoord : TEXCOORD0;
					#ifdef SOFTPARTICLES_ON
					float4 projPos : TEXCOORD1;
					#endif
					//-------------------add----------------------
					float3 vpos : TEXCOORD2;
					//-------------------add----------------------
				};
			
				float4 _MainTex_ST;
 
				v2f vert (appdata_t v)
				{
					v2f o;
					//-------------------add----------------------
					o.vpos = v.vertex.xyz;
					//-------------------add----------------------
					o.vertex = UnityObjectToClipPos(v.vertex);
					#ifdef SOFTPARTICLES_ON
					o.projPos = ComputeScreenPos (o.vertex);
					COMPUTE_EYEDEPTH(o.projPos.z);
					#endif
					o.color = v.color;
					o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
					return o;
				}
 
				sampler2D_float _CameraDepthTexture;
				float _InvFade;
			
				fixed4 frag (v2f i) : SV_Target
				{
					#ifdef SOFTPARTICLES_ON
					float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
					float partZ = i.projPos.z;
					float fade = saturate (_InvFade * (sceneZ-partZ));
					i.color.a *= fade;
					#endif
				
					//-------------------add----------------------
					fixed4 c =2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord);
					c.a *= (i.vpos.x >= _MinX );
	           		c.a *= (i.vpos.x <= _MaxX);
					c.a *= (i.vpos.y >= _MinY);
					c.a *= (i.vpos.y <= _MaxY);
					c.rgb *= c.a;
					return c;
					//-------------------add----------------------
				}
				ENDCG 
			}
		}	
	}
}

下面附上C#代码:

using UnityEngine;
using UnityEngine.UI;

//Mask裁切UI粒子系统
public class MaskShader : MonoBehaviour
{
    private Material material;
    private RectMask2D mask;
    public void Start()
    {
        material = GetComponent<ParticleSystem>().GetComponent<Renderer>().material;
        mask = GetComponentInParent<RectMask2D>();
        SetClip();
        //如果运行时裁剪区域不会发生改变,可以注释掉下面这句代码
        GetComponentInParent<ScrollRect>().onValueChanged.AddListener(v => { SetClip(); });
    }
    public void SetClip()
    {
        //获取到需要裁剪的区域
        Vector3[] corners = new Vector3[4];
        mask.GetComponent<RectTransform>().GetWorldCorners(corners);
        //将裁剪区域传入到Shader中
        material.SetFloat("_MinX", corners[0].x);
        material.SetFloat("_MinY", corners[0].y);
        material.SetFloat("_MaxX", corners[2].x);
        material.SetFloat("_MaxY", corners[2].y);
    }
}

将C#脚本挂到需要裁剪的粒子系统对象身上

效果展示:
裁剪后
裁剪后
裁剪前
裁剪前

附参考链接:
1.https://www.huangshengbo.com/2019/12/12/learnrecord/
2.https://www.xuanyusong.com/archives/3518

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Unity UI中创建水圈波纹的粒子特效,可以按照以下步骤进行操作: 1. 在Unity中创建一个新的UI Image,命名为“WaterCircle”。 2. 在UI Image的“Material”设置中,选择一个支持透明的粒子材质。 3. 在UI Image的“Rect Transform”设置中,将其大小和位置调整为需要添加水圈波纹的位置和大小。 4. 在UI Image的“Canvas Renderer”设置中,将其“Material”设置为刚才选择的粒子材质。 5. 在UI Image的“Mask”组件中,选择一个支持透明的遮罩材质。 6. 在UI Image的“Particle System”组件中,创建一个新的粒子系统,命名为“WaterCircleParticles”。 7. 在粒子系统的“Renderer”设置中,将“Render Mode”设置为“Billboard”;将“Material”设置为刚才选择的粒子材质。 8. 在粒子系统的“Shape”设置中,将“Shape”设置为一个圆形的Emitter,调整“Radius”和“Angle”来控制圆形的大小和方向。 9. 在粒子系统的“Emission”设置中,将“Rate over Time”设置为一个较小的值,例如0.5,使得粒子系统每秒钟只会发射一定数量的粒子。 10. 在粒子系统的“Texture Sheet Animation”设置中,将“Tiles”设置为2x2,将“Frame over Time”设置为一个较小的值,例如0.1,使得粒子系统中的每个粒子可以播放水波纹的动画。 11. 在粒子系统的“Color over Lifetime”设置中,将粒子的颜色从白色渐变到透明,以使得水波纹逐渐消失。 12. 最后,在场景中将UI Image放置在需要添加水圈波纹的位置,并调整其大小和方向即可。 以上是一种简单的创建水圈波纹粒子特效的方法,可以根据具体需求进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值