Unity3D教程:使用Shader实现雪花飘飞效果
发表于2017-01-17
Unity3D 如何实现雪花飘飞的效果呢,这就需要用到Shader,方法其实非常的简单,不会的就一起来看看这个用Unity3D 实现雪花飘飞效果的代码吧。
1.新建一个unity3d 项目,新建一个CameraFilterPack_Atmosphere_Snow_8bits.shader文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | Shader "CameraFilterPack/Atmosphere_Snow_8bits" { Properties { _MainTex ( "Base (RGB)" , 2D) = "white" {} _TimeX ( "Time" , Range(0.0, 1.0)) = 1.0 _ScreenResolution ( "_ScreenResolution" , Vector) = (0.,0.,0.,0.) } SubShader { Pass { ZTest Always CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #pragma target 3.0 #pragma glsl #include "UnityCG.cginc" uniform sampler2D _MainTex; uniform float _TimeX; uniform float _Value; uniform float _Value2; uniform float4 _ScreenResolution; uniform float2 _MainTex_TexelSize; struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { half2 texcoord : TEXCOORD0; float4 vertex : SV_POSITION; fixed4 color : COLOR; }; v2f vert(appdata_t IN) { v2f OUT; OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex); OUT.texcoord = IN.texcoord; OUT.color = IN.color; return OUT; } inline float2 mod(float2 x,float2 modu) { return x - floor(x * (1.0 / modu)) * modu; } inline float rand(float2 co) { float r; co = floor(co*_Value2); r = frac(sin(dot(co.xy,float2(12.9898,78.233))) * 43758.5453); return r; } float4 frag (v2f i) : COLOR { float2 uv = i.texcoord.xy; float3 col=tex2D(_MainTex,uv).rgb; #if UNITY_UV_STARTS_AT_TOP if (_MainTex_TexelSize.y < 0) uv.y = 1-uv.y; #endif float ts=uv.y-.2+sin(uv.x*4.0+7.4*cos(uv.x*10.0))*0.005; uv*=2.0; float c=cos(8*0.01),si=sin(8*0.01); uv=(uv-0.5)*float2(c+si,-si+c); float s=rand(mod(uv * 1.01 +float2(_TimeX,_TimeX)*float2(0.02,0.501),1.0)).r; col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * .9 * _Value)); s=rand(mod(uv * 1.07 +float2(_TimeX,_TimeX)*float2(0.02,0.501),1.0)).r; col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * 1. * _Value)); s=rand(mod(uv+float2(_TimeX,_TimeX)*float2(0.05,0.5),1.0)).r; col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * .98 * _Value)); s=rand(mod(uv * .9 +float2(_TimeX,_TimeX)*float2(0.02,0.51),1.0)).r; col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * .99 * _Value)); s=rand(mod(uv * .75 +float2(_TimeX,_TimeX)*float2(0.07,0.493),1.0)).r; col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.9,1.0, s * 1. * _Value)); s=rand(mod(uv * .5 +float2(_TimeX,_TimeX)*float2(0.03,0.504),1.0)).r; col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.94,1.0, s * 1. * _Value)); s=rand(mod(uv * .3 +float2(_TimeX,_TimeX)*float2(0.02,0.497),1.0)).r; col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.95,1.0, s * 1. * _Value)); s=rand(mod(uv * .1 +float2(_TimeX,_TimeX)*float2(0.0,0.51),1.0)).r; col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.96,1.0, s * 1. * _Value)); s=rand(mod(uv * .03 +float2(_TimeX,_TimeX)*float2(0.0,0.523),1.0)).r; col=lerp(col,float3(1.0,1.0,1.0),smoothstep(0.99,1.0, s * 1. * _Value)); return float4(col,1.0); } ENDCG } } } |
2.为了方便更改shader的一些参数,所以我们新建一个CameraFilterPack_Atmosphere_Snow_8bits.cs 组件类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | using UnityEngine; using System.Collections; [ExecuteInEditMode] [AddComponentMenu ( "Camera Filter Pack/Pixel/Snow_8bits" )] public class CameraFilterPack_Atmosphere_Snow_8bits : MonoBehaviour { #region Variables public Shader SCShader; private float TimeX = 1.0f; private Vector4 ScreenResolution; private Material SCMaterial; [Range(0.9f, 2f)] public float Threshold = 1f; [Range(8f, 256f)] public float Size = 64f; [Range(0f, 10f)] private float Value3 = 1f; [Range(0f, 10f)] private float Value4 = 1f; public static float ChangeValue; public static float ChangeValue2; public static float ChangeValue3; public static float ChangeValue4; #endregion #region Properties Material material { get { if (SCMaterial == null ) { SCMaterial = new Material(SCShader); SCMaterial.hideFlags = HideFlags.HideAndDontSave; } return SCMaterial; } } #endregion void Start () { ChangeValue = Threshold; ChangeValue2 = Size; ChangeValue3 = Value3; ChangeValue4 = Value4; SCShader = Shader.Find( "CameraFilterPack/Atmosphere_Snow_8bits" ); if (!SystemInfo.supportsImageEffects) { enabled = false ; return ; } } void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture) { if (SCShader != null ) { TimeX+=Time.deltaTime; if (TimeX>100) TimeX=0; material.SetFloat( "_TimeX" , TimeX); material.SetFloat( "_Value" , Threshold); material.SetFloat( "_Value2" , Size); material.SetFloat( "_Value3" , Value3); material.SetFloat( "_Value4" , Value4); material.SetVector( "_ScreenResolution" , new Vector4(sourceTexture.width,sourceTexture.height,0.0f,0.0f)); Graphics.Blit(sourceTexture, destTexture, material); } else { Graphics.Blit(sourceTexture, destTexture); } } void OnValidate() { ChangeValue=Threshold; ChangeValue2=Size; ChangeValue3=Value3; ChangeValue4=Value4; } void Update () { if (Application.isPlaying) { Threshold = ChangeValue; Size = ChangeValue2; Value3 = ChangeValue3; Value4 = ChangeValue4; } #if UNITY_EDITOR if (Application.isPlaying!= true ) { SCShader = Shader.Find( "CameraFilterPack/Atmosphere_Snow_8bits" ); } #endif } void OnDisable () { if (SCMaterial) { DestroyImmediate(SCMaterial); } } } |
3.在摄像机上附加AddCameraFilter.cs组件,为了方便控制看出效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | using UnityEngine; public class AddCameraFilter : MonoBehaviour { private CameraFilterPack_Atmosphere_Snow_8bits _cameraFilterPack; // Use this for initialization void Start() { _cameraFilterPack = GetComponent } // Update is called once per frame void OnGUI() { if (GUI.Button( new Rect(50, 200, 200, 30), "添加雪花效果" )) { if (_cameraFilterPack == null ) _cameraFilterPack = gameObject.AddComponent if (_cameraFilterPack != null ) _cameraFilterPack.enabled = true ; } if (GUI.Button( new Rect(50, 250, 200, 30), "移除雪花效果" )) { if (_cameraFilterPack != null ) _cameraFilterPack.enabled = false ; } } } |
4.最后我们直接运行项目看效果。

