查看: 1488|回复: 0
打印 上一主题 下一主题

[Shaders] Unity3D 实现雪花飘飞效果[Shader](三)

[复制链接]

14

主题

1

听众

272

积分

设计实习生

Rank: 2

纳金币
35
精华
0
跳转到指定楼层
楼主
发表于 2017-1-6 13:06:48 |只看该作者 |倒序浏览
     今天为大家分享一下,如何写一个雪花效果的Shader,因为操作过程比较简单,我直接上代码啦!
     欢迎加我的学习交流群:575561285

    1.新建一个unity3d 项目,新建一个CameraFilterPack_Atmosphere_Snow_8bits.shader文件。
  1. Shader "CameraFilterPack/Atmosphere_Snow_8bits" {
  2. Properties
  3. {
  4. _MainTex ("Base (RGB)", 2D) = "white" {}
  5. _TimeX ("Time", Range(0.0, 1.0)) = 1.0
  6. _ScreenResolution ("_ScreenResolution", Vector) = (0.,0.,0.,0.)
  7. }
  8. SubShader
  9. {
  10. Pass
  11. {
  12. ZTest Always
  13. CGPROGRAM
  14. #pragma vertex vert
  15. #pragma fragment frag
  16. #pragma fragmentoption ARB_precision_hint_fastest
  17. #pragma target 3.0
  18. #pragma glsl
  19. #include "UnityCG.cginc"
  20. uniform sampler2D _MainTex;
  21. uniform float _TimeX;
  22. uniform float _Value;
  23. uniform float _Value2;
  24. uniform float4 _ScreenResolution;
  25. uniform float2 _MainTex_TexelSize;
  26. struct appdata_t
  27. {
  28. float4 vertex   : POSITION;
  29. float4 color    : COLOR;
  30. float2 texcoord : TEXCOORD0;
  31. };
  32. struct v2f
  33. {
  34. half2 texcoord  : TEXCOORD0;
  35. float4 vertex   : SV_POSITION;
  36. fixed4 color    : COLOR;
  37. };
  38. v2f vert(appdata_t IN)
  39. {
  40. v2f OUT;
  41. OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
  42. OUT.texcoord = IN.texcoord;
  43. OUT.color = IN.color;
  44. return OUT;
  45. }

  46. inline float2 mod(float2 x,float2 modu) {
  47.   return x - floor(x * (1.0 / modu)) * modu;
  48. }


  49. inline float rand(float2 co)
  50. {
  51.         float r;
  52.         co = floor(co*_Value2);
  53.         r = frac(sin(dot(co.xy,float2(12.9898,78.233))) * 43758.5453);
  54.    return r;
  55. }

  56. float4 frag (v2f i) : COLOR
  57. {
  58.         float2 uv = i.texcoord.xy;
  59.        
  60.     float3 col=tex2D(_MainTex,uv).rgb;
  61.         #if UNITY_UV_STARTS_AT_TOP
  62. if (_MainTex_TexelSize.y < 0)
  63. uv.y = 1-uv.y;
  64. #endif
  65.    float ts=uv.y-.2+sin(uv.x*4.0+7.4*cos(uv.x*10.0))*0.005;

  66.     uv*=2.0;
  67.    
  68.     float c=cos(8*0.01),si=sin(8*0.01);
  69.         uv=(uv-0.5)*float2(c+si,-si+c);       
  70.    
  71.     float s=rand(mod(uv * 1.01 +float2(_TimeX,_TimeX)*float2(0.02,0.501),1.0)).r;
  72.     col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * .9 * _Value));
  73.    
  74.         s=rand(mod(uv * 1.07 +float2(_TimeX,_TimeX)*float2(0.02,0.501),1.0)).r;
  75.         col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * 1. * _Value));
  76.    
  77.         s=rand(mod(uv+float2(_TimeX,_TimeX)*float2(0.05,0.5),1.0)).r;
  78.     col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * .98 * _Value));
  79.        
  80.         s=rand(mod(uv * .9 +float2(_TimeX,_TimeX)*float2(0.02,0.51),1.0)).r;
  81.     col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * .99 * _Value));
  82.        
  83.         s=rand(mod(uv * .75 +float2(_TimeX,_TimeX)*float2(0.07,0.493),1.0)).r;
  84.     col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * 1. * _Value));
  85.        
  86.         s=rand(mod(uv * .5 +float2(_TimeX,_TimeX)*float2(0.03,0.504),1.0)).r;
  87.     col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.94,1.0, s * 1. * _Value));
  88.        
  89.         s=rand(mod(uv * .3 +float2(_TimeX,_TimeX)*float2(0.02,0.497),1.0)).r;
  90.     col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.95,1.0, s * 1. * _Value));
  91.        
  92.         s=rand(mod(uv * .1 +float2(_TimeX,_TimeX)*float2(0.0,0.51),1.0)).r;
  93.         col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.96,1.0, s * 1. * _Value));
  94.        
  95.         s=rand(mod(uv * .03 +float2(_TimeX,_TimeX)*float2(0.0,0.523),1.0)).r;
  96.         col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.99,1.0, s * 1. * _Value));
  97.    
  98.         return  float4(col,1.0);
  99. }
  100. ENDCG
  101. }
  102. }
  103. }
复制代码
2.为了方便更改shader的一些参数,所以我们新建一个CameraFilterPack_Atmosphere_Snow_8bits.cs 组件类。
  1. using UnityEngine;
  2. using System.Collections;
  3. [ExecuteInEditMode]
  4. [AddComponentMenu ("Camera Filter Pack/Pixel/Snow_8bits")]
  5. public class CameraFilterPack_Atmosphere_Snow_8bits : MonoBehaviour {
  6. #region Variables
  7. public Shader SCShader;
  8. private float TimeX = 1.0f;
  9. private Vector4 ScreenResolution;
  10. private Material SCMaterial;
  11. [Range(0.9f, 2f)]
  12. public float Threshold = 1f;
  13. [Range(8f, 256f)]
  14. public float Size = 64f;
  15. [Range(0f, 10f)]
  16. private float Value3 = 1f;
  17. [Range(0f, 10f)]
  18. private float Value4 = 1f;
  19. public static float ChangeValue;
  20. public static float ChangeValue2;
  21. public static float ChangeValue3;
  22. public static float ChangeValue4;
  23. #endregion
  24. #region Properties
  25. Material material
  26. {
  27. get
  28. {
  29. if(SCMaterial == null)
  30. {
  31. SCMaterial = new Material(SCShader);
  32. SCMaterial.hideFlags = HideFlags.HideAndDontSave;
  33. }
  34. return SCMaterial;
  35. }
  36. }
  37. #endregion
  38. void Start ()
  39. {
  40. ChangeValue = Threshold;
  41. ChangeValue2 = Size;
  42. ChangeValue3 = Value3;
  43. ChangeValue4 = Value4;
  44. SCShader = Shader.Find("CameraFilterPack/Atmosphere_Snow_8bits");
  45. if(!SystemInfo.supportsImageEffects)
  46. {
  47. enabled = false;
  48. return;
  49. }
  50. }

  51. void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture)
  52. {
  53. if(SCShader != null)
  54. {
  55. TimeX+=Time.deltaTime;
  56. if (TimeX>100)  TimeX=0;
  57. material.SetFloat("_TimeX", TimeX);
  58. material.SetFloat("_Value", Threshold);
  59. material.SetFloat("_Value2", Size);
  60. material.SetFloat("_Value3", Value3);
  61. material.SetFloat("_Value4", Value4);
  62. material.SetVector("_ScreenResolution",new Vector4(sourceTexture.width,sourceTexture.height,0.0f,0.0f));
  63. Graphics.Blit(sourceTexture, destTexture, material);
  64. }
  65. else
  66. {
  67. Graphics.Blit(sourceTexture, destTexture);
  68. }
  69. }
  70. void OnValidate()
  71. {
  72.                 ChangeValue=Threshold;
  73.                 ChangeValue2=Size;
  74.                 ChangeValue3=Value3;
  75.                 ChangeValue4=Value4;
  76. }
  77. void Update ()
  78. {
  79. if (Application.isPlaying)
  80. {
  81. Threshold = ChangeValue;
  82. Size = ChangeValue2;
  83. Value3 = ChangeValue3;
  84. Value4 = ChangeValue4;
  85. }
  86. #if UNITY_EDITOR
  87. if (Application.isPlaying!=true)
  88. {
  89. SCShader = Shader.Find("CameraFilterPack/Atmosphere_Snow_8bits");
  90. }
  91. #endif
  92. }
  93. void OnDisable ()
  94. {
  95. if(SCMaterial)
  96. {
  97. DestroyImmediate(SCMaterial);
  98. }
  99. }
  100. }
复制代码
3.在摄像机上附加AddCameraFilter.cs组件,为了方便控制看出效果。
  1. using UnityEngine;

  2. public class AddCameraFilter : MonoBehaviour {

  3.     private CameraFilterPack_Atmosphere_Snow_8bits _cameraFilterPack;
  4.     // Use this for initialization
  5.     void Start()
  6.     {
  7.         _cameraFilterPack = GetComponent<CameraFilterPack_Atmosphere_Snow_8bits>();
  8.     }

  9.     // Update is called once per frame
  10.     void OnGUI()
  11.     {

  12.         if (GUI.Button(new Rect(50, 200, 200, 30), "添加雪花效果"))
  13.         {
  14.             if (_cameraFilterPack == null)
  15.                 _cameraFilterPack = gameObject.AddComponent<CameraFilterPack_Atmosphere_Snow_8bits>();
  16.             if (_cameraFilterPack != null)
  17.                 _cameraFilterPack.enabled = true;
  18.         }
  19.         if (GUI.Button(new Rect(50, 250, 200, 30), "移除雪花效果"))
  20.         {
  21.             if (_cameraFilterPack != null)
  22.                 _cameraFilterPack.enabled = false;
  23.         }
  24.     }
  25. }
复制代码
4.好吧!最后我们直接运行项目看效果噢!
4_0.png

4_1.png
   
    学习交流群:575561285
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-15 11:07 , Processed in 0.260848 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部