天天看點

Mask裁切UI粒子特效或者3D模型 Mask裁切UI粒子特效或者3D模型

Mask裁切UI粒子特效或者3D模型

剛好前幾天有人問我這個問題,再加上新項目也可能用,是以這兩天就研究了一下。其實如果粒子特效 和3D模型 都用RenderTexture來做的話就不會有裁切的問題,但是粒子特效用RenderTexture來做會有顯示的問題,是以還是得用錄影機。廢話不多說了,進入正題。

原理就是把Mask的裁切區域傳給粒子特效Shader,當超出這個區域那麼直接讓它完全透明即可。粒子特效的源生shader大家可以去unity官網下載下傳,我在這裡把需要修改的地方标注給大家。

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

[C#] 純文字檢視 複制代碼 ?

  001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103

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。

[C#] 純文字檢視 複制代碼 ?

  01 02 03 04 05 06 07 08 09 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

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);

}

}

}

}

OK,如下圖所示,把粒子特效直接挂在Mask下面, 就可以進行裁切了。。
Mask裁切UI粒子特效或者3D模型 Mask裁切UI粒子特效或者3D模型

1.png (181.88 KB, 下載下傳次數: 0)

下載下傳附件  儲存到相冊

2015-7-8 17:50 上傳

繼續閱讀