Unity 之残影实现

分享部分代码如下,可做为参考:

 1 using System.Collections;
 2 using UnityEngine;
 3 
 4 namespace ACTBook
 5 {
 6     public class ShadowFx : MonoBehaviour
 7     {
 8         const string SHADOW_FX_NAME_PREFIX = "Shadow_";
 9         public Shader shader;//透明边缘泛光Shader
10         public SkinnedMeshRenderer skinnedMeshRenderer;//蒙皮网格
11         public float fadeTime = 0.5f;//淡出时间
12         public MonoBehaviour coroutineMonoBehaviour;
13         //协程开启对象,防止因自身关闭导致残影协程停止
14         GameObject mShadowFxGO;
15 
16 
17         void OnEnable()
18         {
19             coroutineMonoBehaviour.StartCoroutine(ShadowFxTrigger());//残影特效触发协程
20         }
21 
22         void OnDestroy()
23         {
24             if (mShadowFxGO)//特殊情况残影销毁处理
25                 Destroy(mShadowFxGO);
26         }
27 
28         IEnumerator ShadowFxTrigger()
29         {
30             mShadowFxGO = new GameObject(SHADOW_FX_NAME_PREFIX + Time.time);
31             mShadowFxGO.transform.position = skinnedMeshRenderer.transform.position;
32             mShadowFxGO.transform.rotation = skinnedMeshRenderer.transform.rotation;
33             mShadowFxGO.transform.localScale = skinnedMeshRenderer.transform.localScale;
34             //拷贝变换信息
35             var meshRenderer = mShadowFxGO.AddComponent<MeshRenderer>();
36             var meshFilter = mShadowFxGO.AddComponent<MeshFilter>();
37             var mesh = new Mesh() { name = mShadowFxGO.name };
38             skinnedMeshRenderer.BakeMesh(mesh);//烘焙残影
39             meshFilter.sharedMesh = mesh;
40             var mat = new Material(shader);
41             mat.CopyPropertiesFromMaterial(skinnedMeshRenderer.sharedMaterial);
42             //从主材质球拷贝参数
43             meshRenderer.sharedMaterial = mat;
44             var cacheMatColor = mat.color;
45             var beginTime = Time.time;
46             for (var duration = fadeTime; Time.time - beginTime <= duration;)
47             {
48                 var t = (Time.time - beginTime) / duration;
49                 mat.color = new Color(cacheMatColor.r, cacheMatColor.g, cacheMatColor.b, Mathf.Lerp(1f, 0f, t));
50                 yield return null;
51             }//残影消隐插值
52             //Destroy(mShadowFxGO);//销毁残影
53         }
54     }
55 }

shader如下:

 1 Shader "ACTBook/RimFxShader"
 2 {
 3     Properties
 4     {
 5         _Color ("Color", Color) = (1,1,1,1)
 6         _MainTex ("Albedo (RGB)", 2D) = "white" {}
 7         _Glossiness ("Smoothness", Range(0,1)) = 0.5
 8         _Metallic ("Metallic", Range(0,1)) = 0.0
 9         //一些常规字段
10         _BumpMap("Normal Texture (RGB)", 2D) = "white" {}//法线贴图
11         _RimColor("Rim Color", Color) = (1,0.0, 0.0, 0.0)//发光颜色
12         _RimPower("Rim Power", float) = 2.0//发光强度
13     }
14     SubShader
15     {
16         Tags
17         {
18             "Queue" = "Transparent"
19             "RenderType" = "Transparent"
20         }//半透明Shader标签声明
21 
22         Pass
23         {
24             ZWrite On
25             ColorMask 0
26         }//预先写深度
27 
28         CGPROGRAM
29         #pragma surface surf Standard fullforwardshadows alpha:fade
30         //留意alpha:fade,使用半透明Shader须加入这一段
31         #pragma target 3.0
32         sampler2D _MainTex;
33         fixed4 _RimColor;//边缘发光的颜色
34         half _RimPower;//边缘发光的强度
35         struct Input
36         {
37             float2 uv_MainTex;
38             float2 uv_BumpMap;
39             half3 viewDir;
40             //边缘发光所需要的缺省参数
41         };
42         sampler2D _BumpMap;
43         half _Glossiness;
44         half _Metallic;
45         fixed4 _Color;
46         UNITY_INSTANCING_BUFFER_START(Props)
47         UNITY_INSTANCING_BUFFER_END(Props)
48 
49         void surf (Input IN, inout SurfaceOutputStandard o)
50         {
51             o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
52             half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
53             //计算边缘光强度
54             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
55             o.Albedo = c.rgb;
56             o.Metallic = _Metallic;
57             o.Smoothness = _Glossiness;
58             o.Emission = _RimColor.rgb * pow(rim, _RimPower);
59             //乘以边缘光颜色并赋予自发光通道
60             o.Alpha = rim * c.a;//边缘光强度与颜色alpha相乘,并赋予Alphat通道
61         }
62         ENDCG
63     }
64 }

转载请注明出处:https://www.cnblogs.com/jietian331/p/15841848.html

posted @ 2022-01-25 10:07  孤独の巡礼  阅读(272)  评论(0编辑  收藏  举报