日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2024/9/30 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Shader相关Mask裁切UI粒子特效或者3D模型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

轉(zhuǎn)載自:http://www.xuanyusong.com/archives/3518

?

原理就是把Mask的裁切區(qū)域傳給粒子特效Shader,當(dāng)超出這個區(qū)域那么直接讓它完全透明即可。粒子特效的源生shader大家可以去unity官網(wǎng)下載,我在這里把需要修改的地方標(biāo)注給大家。

//add 注釋中的內(nèi)容就是我做修改的地方。

1

2

3

4

5

6

7

8

9

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

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

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的區(qū)域傳給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;//
開發(fā)時分辨率寬
int designHeight = 640;//
開發(fā)時分辨率高
float s1 = (float)designWidth / (float)designHeight;
float s2 = (float)width / (float)height;

//目標(biāo)分辨率小于 960X640 需要計(jì)算縮放比例
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 是因?yàn)?/span>ugui默認(rèn)的縮放比例是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);
}
}
}
}
上面這段代碼寫的不太好,有一個更好的辦法來取Mask的裁切區(qū)域。

通過GetWorlCornets來確定裁切的區(qū)域

1

2

3

4

5

6

7

????????Vector3[] corners = new Vector3[4];

????????RectTransform rectTransform = transform as RectTransform;

????????rectTransform.GetWorldCorners (corners);

????????minX = corners [0].x;

????????minY = corners [0].y;

????????maxX = corners [2].x;

????????maxY = corners [2].y;

然后在把裁切的區(qū)域傳到shader中。

1

2

3

4

5

????????Material m = GetMaterial (renderer);

????????m.SetFloat("_MinX",minX);

????????m.SetFloat("_MinY",minY);

????????m.SetFloat("_MaxX",maxX);

????????m.SetFloat("_MaxY",maxY);

為了做到不影響美術(shù),所以美術(shù)開發(fā)特效的時候還是用以前的shader。程序在運(yùn)行中對它進(jìn)行更換,這樣可以無縫進(jìn)行切換。

如果運(yùn)行時裁切區(qū)域發(fā)生變化, 可以重寫OnRectTransformDimensionsChange()方法來重新給材質(zhì)賦新的裁切區(qū)域

1

2

3

4

5

????protected override void OnRectTransformDimensionsChange ()

????{

????????base.OnRectTransformDimensionsChange ();

????????Change ();//重新再給材質(zhì)賦裁切參數(shù)

????}

OK,如下圖所示,把粒子特效直接掛在Mask下面, 就可以進(jìn)行裁切了。。

在說一下3D模型, 理論上用上述的shader改一改就可以。 但是我還是建議3D模型用RenderTexture。比較好控制深度。

?

?

總結(jié)

以上是生活随笔為你收集整理的Shader相关Mask裁切UI粒子特效或者3D模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。