能量盾 受击波纹 小测试

 表现:受击是会产生一个受击波纹向四周扩散

shader:
  1. Shader "Unlit/NewUnlitShader"
  2. {
  3. Properties
  4. {
  5. _ShieldColor ("Shield Color", Color) = (0.5,0.5,0.5,0)
  6. _BaseTex ("Base Texture", 2D) = "white" {}
  7. _HitMaskTex ("Hit Mask Tex", 2D) = "white" {}
  8. _HitU ("Hit U", Range(0, 1)) = 0.5
  9. _HitV ("Hit V", Range(0, 1)) = 0.5
  10. _HitOffset ("Hit Offset", Range(0, 2)) = 0.5
  11. _HitU2 ("Hit U2", Range(0, 1)) = 0.5
  12. _HitV2 ("Hit V2", Range(0, 1)) = 0.5
  13. _HitOffset2 ("Hit Offset2", Range(0, 2)) = 0.5
  14. }
  15. SubShader
  16. {
  17. Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
  18. Blend SrcAlpha One
  19. Cull Off Lighting Off ZWrite Off
  20. LOD 100
  21. Pass
  22. {
  23. CGPROGRAM
  24. #pragma vertex vert
  25. #pragma fragment frag
  26. #include "UnityCG.cginc"
  27. fixed4 _ShieldColor;
  28. sampler2D _BaseTex;
  29. float4 _BaseTex_ST;
  30. sampler2D _HitMaskTex;
  31. float4 _HitMaskTex_ST;
  32. fixed _HitU;
  33. fixed _HitV;
  34. fixed _HitOffset;
  35. fixed _HitU2;
  36. fixed _HitV2;
  37. fixed _HitOffset2;
  38. fixed luminance(fixed3 color) {
  39. return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;
  40. }
  41. struct appdata
  42. {
  43. float4 vertex : POSITION;
  44. float2 uv : TEXCOORD0;
  45. };
  46. struct v2f
  47. {
  48. float4 vertex : SV_POSITION;
  49. float2 baseuv : TEXCOORD0;
  50. };
  51. v2f vert (appdata v)
  52. {
  53. v2f o;
  54. o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
  55. o.baseuv = TRANSFORM_TEX(v.uv, _BaseTex);
  56. return o;
  57. }
  58. fixed4 frag (v2f i) : SV_Target
  59. {
  60. fixed lum = luminance(tex2D(_BaseTex, i.baseuv));
  61. fixed3 baseCol = _ShieldColor * lum;
  62. fixed dis = distance(fixed2(_HitU, _HitV), i.baseuv);
  63. dis = abs(dis - _HitOffset);
  64. dis = luminance(tex2D(_HitMaskTex, dis));
  65. fixed3 hitCol = _ShieldColor * dis;
  66. dis = distance(fixed2(_HitU2, _HitV2), i.baseuv);
  67. dis = abs(dis - _HitOffset2);
  68. dis = luminance(tex2D(_HitMaskTex, dis));
  69. fixed3 hitCol2 = _ShieldColor * dis;
  70. return fixed4(baseCol + hitCol + hitCol2, lum);
  71. }
  72. ENDCG
  73. }
  74. }
  75. }

C#
  1. using UnityEngine;
  2. using System.Collections;
  3. public class HitShieldTest : MonoBehaviour
  4. {
  5. Material ShieldMaterial;
  6. Vector3 oriPos;
  7. Vector3 extents;
  8. float hitTime;
  9. float hitTime2;
  10. void Awake()
  11. {
  12. ShieldMaterial = GetComponent<MeshRenderer>().material;
  13. Collider collider = GetComponent<Collider>();
  14. extents = collider.bounds.extents;
  15. oriPos = transform.position + extents;
  16. ShieldMaterial.SetFloat("_HitOffset", 2);
  17. ShieldMaterial.SetFloat("_HitOffset2", 2);
  18. hitTime = float.MinValue;
  19. hitTime2 = float.MinValue;
  20. }
  21. // Update is called once per frame
  22. void Update()
  23. {
  24. if (ShieldMaterial == null)
  25. {
  26. return;
  27. }
  28. if (Input.GetKeyDown(KeyCode.Mouse0))
  29. {
  30. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  31. RaycastHit hit;
  32. if (Physics.Raycast(ray, out hit))
  33. {
  34. Vector3 dis = oriPos - hit.point;
  35. dis = dis / (2 * extents.x); //方形
  36. if (Time.time - hitTime > 0.5f)
  37. {
  38. hitTime = Time.time;
  39. ShieldMaterial.SetFloat("_HitU", dis.x);
  40. ShieldMaterial.SetFloat("_HitV", dis.y);
  41. }
  42. else if (Time.time - hitTime2 > 0.5f)
  43. {
  44. hitTime2 = Time.time;
  45. ShieldMaterial.SetFloat("_HitU2", dis.x);
  46. ShieldMaterial.SetFloat("_HitV2", dis.y);
  47. }
  48. }
  49. }
  50. if (Time.time - hitTime <= 2)
  51. {
  52. ShieldMaterial.SetFloat("_HitOffset", Time.time - hitTime);
  53. }
  54. if (Time.time - hitTime2 <= 2)
  55. {
  56. ShieldMaterial.SetFloat("_HitOffset2", Time.time - hitTime2);
  57. }
  58. }
  59. }

优化一下 支持帧动画,实际表现也不是很好
再优化的话,考虑在程序中吧受击点定位到最相近的格子的中心点,动画的叠加表现就会很好

  1. Shader "Unlit/NewUnlitShader"
  2. {
  3. Properties
  4. {
  5. _ShieldColor ("Shield Color", Color) = (0.5,0.5,0.5,0)
  6. _BaseTex ("Base Texture", 2D) = "white" {}
  7. //圆形用渐变贴图的方式
  8. _HitMaskTex ("Hit Mask Tex", 2D) = "white" {}
  9. //帧动画的方式
  10. _HitAniTex ("Hit Animation Tex", 2D) = "white" {}
  11. _HitAniHorAmount ("Horizontal Amount", float) = 1
  12. _HitAniVerAmount ("Vertical Amount", float) = 1
  13. //受击点信息
  14. _HitU ("Hit U", Range(0, 1)) = 0.5
  15. _HitV ("Hit V", Range(0, 1)) = 0.5
  16. _HitOffset ("Hit Offset", Range(0, 2)) = 0.5
  17. _HitU2 ("Hit U2", Range(0, 1)) = 0.5
  18. _HitV2 ("Hit V2", Range(0, 1)) = 0.5
  19. _HitOffset2 ("Hit Offset2", Range(0, 2)) = 0.5
  20. }
  21. SubShader
  22. {
  23. Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
  24. Blend SrcAlpha One
  25. Cull Off Lighting Off ZWrite Off
  26. LOD 100
  27. Pass
  28. {
  29. CGPROGRAM
  30. #pragma vertex vert
  31. #pragma fragment frag
  32. #include "UnityCG.cginc"
  33. fixed4 _ShieldColor;
  34. sampler2D _BaseTex;
  35. float4 _BaseTex_ST;
  36. sampler2D _HitMaskTex;
  37. float4 _HitMaskTex_ST;
  38. sampler2D _HitAniTex;
  39. float4 _HitAniTex_ST;
  40. fixed _HitAniHorAmount;
  41. fixed _HitAniVerAmount;
  42. fixed _HitU;
  43. fixed _HitV;
  44. fixed _HitOffset;
  45. fixed _HitU2;
  46. fixed _HitV2;
  47. fixed _HitOffset2;
  48. fixed luminance(fixed3 color) {
  49. return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;
  50. }
  51. struct appdata
  52. {
  53. float4 vertex : POSITION;
  54. float2 uv : TEXCOORD0;
  55. };
  56. struct v2f
  57. {
  58. float4 vertex : SV_POSITION;
  59. float2 baseuv : TEXCOORD0;
  60. };
  61. v2f vert (appdata v)
  62. {
  63. v2f o;
  64. o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
  65. o.baseuv = TRANSFORM_TEX(v.uv, _BaseTex);
  66. return o;
  67. }
  68. fixed4 frag (v2f i) : SV_Target
  69. {
  70. fixed lum = luminance(tex2D(_BaseTex, i.baseuv));
  71. fixed3 baseCol = _ShieldColor * lum;
  72. fixed dis = distance(fixed2(_HitU, _HitV), i.baseuv);
  73. dis = abs(dis - _HitOffset);
  74. dis = luminance(tex2D(_HitMaskTex, dis));
  75. fixed3 hitCol = _ShieldColor * dis;
  76. dis = distance(fixed2(_HitU2, _HitV2), i.baseuv);
  77. dis = abs(dis - _HitOffset2);
  78. dis = luminance(tex2D(_HitMaskTex, dis));
  79. fixed3 hitCol2 = _ShieldColor * dis;
  80. //return fixed4(baseCol + hitCol + hitCol2, lum);
  81. //帧动画受击
  82. //单帧的uv值
  83. half2 aniuv = i.baseuv + half2(0.5 - _HitU, 0.5 - _HitV);
  84. aniuv = 2 * (aniuv - half2(0.5, 0.5)) + half2(0.5, 0.5);
  85. aniuv.x = saturate(aniuv.x);
  86. aniuv.y = saturate(aniuv.y);
  87. //单帧位置(行列)
  88. float idx = floor(_Time.y * _HitAniHorAmount * _HitAniVerAmount);
  89. idx = idx % (_HitAniHorAmount * _HitAniVerAmount);
  90. float row = floor(idx / _HitAniHorAmount);
  91. float col = idx - row * _HitAniHorAmount;
  92. //转化为全图的uv值
  93. aniuv = aniuv + half2(col, _HitAniVerAmount - 1 - row);
  94. aniuv.x /= _HitAniHorAmount;
  95. aniuv.y /= _HitAniVerAmount;
  96. fixed4 aniCol = tex2D(_HitAniTex, aniuv);
  97. aniCol.rgb = luminance(aniCol) * _ShieldColor;
  98. aniCol.rgb *= aniCol.a;
  99. return fixed4(baseCol + aniCol, lum);
  100. }
  101. ENDCG
  102. }
  103. }
  104. }




原文地址:https://www.cnblogs.com/Hichy/p/6723886.html