• 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

  • 相关阅读:
    HDU
    HDU
    [JSOI2009]计数问题 二维树状数组BZOJ 1452
    THU 上机 最小邮票数 暴力枚举
    SJTU 机试 最小面积子矩阵 压缩+双指针
    SJTU 机试 数学
    Preprefix sum BZOJ 3155 树状数组
    [HNOI2004]树的计数 BZOJ 1211 prufer序列
    HDU 5009
    上下界网络流模型常见解法
  • 原文地址:https://www.cnblogs.com/jietian331/p/15841848.html
Copyright © 2020-2023  润新知