UGUI教程之-Mask裁切UI粒子特效

 

其实如果粒子特效 和3D模型 都用RenderTexture来做的话就不会有裁切的问题,但是粒子特效用RenderTexture来做会有显示的问题,所以还是得用摄像机。废话不多说了,进入正题。我们来看下用Mask裁切UI粒子特效,原理就是把Mask的裁切区域传给粒子特效Shader,当超出这个区域那么直接让它完全透明即可。粒子特效的源生shader大家可以去unity官网下载,我在这里把需要修改的地方标注给大家。下面是效果图

贴上代码:

//add 注释中的内容就是我做修改的地方。


Shader "Particles/Additive" {
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 = mul(UNITY_MATRIX_MVP, 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
}
}
}
}

然后是自己写了个类继承Mask。把Mask的区域传给shader。


using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class MyMask :Mask
{
protected override void Start ()
{
base.Start ();

int width = Screen.width;
int height = Screen.height;
int designWidth = 960;//开发时分辨率宽
int designHeight = 640;//开发时分辨率高
float s1 = (float)designWidth / (float)designHeight;
float s2 = (float)width / (float)height;

//目标分辨率小于 960X640的 需要计算缩放比例
float contentScale =1f;
if(s1 > s2) {
contentScale = s1/s2;
}
Canvas  canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
Vector2 pos;
if(RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, transform.position, canvas.camera, out pos)){
ParticleSystem  [] particlesSystems  = transform.GetComponentsInChildren<ParticleSystem>();
RectTransform rectTransform = transform as RectTransform;
float minX,minY,maxX,maxY;
minX = rectTransform.rect.x  + pos.x;
minY = rectTransform.rect.y+ pos.y;
maxX = minX + rectTransform.rect.width ;
maxY = minY + rectTransform.rect.height;


//这里 100  是因为ugui默认的缩放比例是100  你也可以去改这个值,但是我觉得最好别改。
foreach(ParticleSystem particleSystem in particlesSystems)
{
particleSystem.renderer.sharedMaterial.SetFloat("_MinX",minX/100/contentScale);
particleSystem.renderer.sharedMaterial.SetFloat("_MinY",minY/100/contentScale);
particleSystem.renderer.sharedMaterial.SetFloat("_MaxX",maxX/100/contentScale);
particleSystem.renderer.sharedMaterial.SetFloat("_MaxY",maxY/100/contentScale);
}
}
}
}

下面是工程下载地址:

UGUI-Particle.txt (下载392 )

好了,本篇UGUI教程到此结束,下篇我们再会!