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 AlwaysCGPROGRAM#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_TOPif (_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 Variablespublic 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 PropertiesMaterial material{get{if(SCMaterial == null){SCMaterial = new Material(SCShader);SCMaterial.hideFlags = HideFlags.HideAndDontSave;}return SCMaterial;}}#endregionvoid 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_EDITORif (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.最后我们直接运行项目看效果。


