工程截图
一、创建Shader
//将官方的Bumped Specular Shader,增加边缘发光功能 Shader "Custom/RimEmission-Bumped Specular" { Properties{ _Color("Main Color", Color) = (1,1,1,1) _SpecColor("Specular Color", Color) = (0.5, 0.5, 0.5, 1) [PowerSlider(5.0)] _Shininess("Shininess", Range(0.03, 1)) = 0.078125 _MainTex("Base (RGB) Gloss (A)", 2D) = "white" {} _BumpMap("Normalmap", 2D) = "bump" {} //增加边缘 [PerRendererData] _RimColor("Rim Color", Color) = (1,1,1,1) } CGINCLUDE sampler2D _MainTex; sampler2D _BumpMap; fixed4 _Color; half _Shininess; fixed4 _RimColor; float _RimPower; struct Input { float2 uv_MainTex; float2 uv_BumpMap; float3 viewDir; }; void surf(Input IN, inout SurfaceOutput o) { fixed4 tex = tex2D(_MainTex, IN.uv_MainTex); o.Albedo = tex.rgb * _Color.rgb; o.Gloss = tex.a; o.Alpha = tex.a * _Color.a; o.Specular = _Shininess; //o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); } ENDCG SubShader{ Tags { "RenderType" = "Opaque" } LOD 400 CGPROGRAM //增加finalColor函数 #pragma surface surf BlinnPhong finalcolor:RimColor #pragma target 3.0 void RimColor(Input IN, SurfaceOutput o, inout fixed4 color) { //求法线与视线的夹角cos half rim = 1.0 - saturate(dot(normalize(IN.viewDir),o.Normal)); color = lerp(color * _RimColor, color, rim); } ENDCG } SubShader{ Tags { "RenderType" = "Opaque" } LOD 400 CGPROGRAM #pragma surface surf BlinnPhong nodynlightmap ENDCG } FallBack "Legacy Shaders/Specular" }
二、创建闪烁控制脚本
using UnityEngine; /// <summary> /// 控制材质边缘闪烁效果 /// </summary> public class RimTwinkleEffect : MonoBehaviour { public Renderer render; public Color startColor; public Color endColor; public float speed = 1.0f; public bool active = true; private MaterialPropertyBlock property; private float t=0; private bool reverse = false; private void Awake() { property = new MaterialPropertyBlock(); } void Update() { if (!active) return; if (reverse) { t -= speed * Time.deltaTime; if (t <= 0) reverse = false; } else { t += speed * Time.deltaTime; if (t >= 1) reverse = true; } Color color = Color.Lerp(startColor, endColor, t); SetRimColor(color); } public void SetRimColor(Color color) { property.SetColor( "_RimColor", color ); render.SetPropertyBlock(property); } public void Begin() { active = true; SetRimColor(startColor); } public void Stop() { active = false; SetRimColor(startColor); } }