SHOW:
|
|
- or go back to the newest paste.
1 | Shader "Toon/Lit Snow" { | |
2 | Properties{ | |
3 | [Header(Main)] | |
4 | _Noise("Snow Noise", 2D) = "gray" {} | |
5 | _NoiseScale("Noise Scale", Range(0,2)) = 0.1 | |
6 | _NoiseWeight("Noise Weight", Range(0,2)) = 0.1 | |
7 | [HDR]_ShadowColor("Shadow Color", Color) = (0.5,0.5,0.5,1) | |
8 | [Space] | |
9 | [Header(Tesselation)] | |
10 | _MaxTessDistance("Max Tessellation Distance", Range(10,100)) = 50 | |
11 | _Tess("Tessellation", Range(1,32)) = 20 | |
12 | [Space] | |
13 | [Header(Snow)] | |
14 | [HDR]_Color("Snow Color", Color) = (0.5,0.5,0.5,1) | |
15 | _MainTex("Snow Texture", 2D) = "white" {} | |
16 | _SnowHeight("Snow Height", Range(0,2)) = 0.3 | |
17 | _SnowTextureOpacity("Snow Texture Opacity", Range(0,1)) = 0.3 | |
18 | _SnowTextureScale("Snow Texture Scale", Range(0,2)) = 0.3 | |
19 | ||
20 | [Space] | |
21 | [Header(Snow Path)] | |
22 | _PathBlending("Path Color Blending", Range(0,3)) = 2 | |
23 | _SnowPathStrength("Snow Path Smoothness", Range(0,4)) = 2 | |
24 | [HDR]_PathColorIn("Snow Path Color", Color) = (1,1,1,1) | |
25 | [HDR]_PathColorOut("Snow Path Color2", Color) = (0.5,0.5,1,1) | |
26 | ||
27 | [Space] | |
28 | [Header(Sparkles)] | |
29 | _SparkleScale("Sparkle Scale", Range(0,10)) = 10 | |
30 | _SparkCutoff("Sparkle Cutoff", Range(0,10)) = 0.9 | |
31 | _SparkleNoise("Sparkle Noise", 2D) = "gray" {} | |
32 | [Space] | |
33 | [Header(Rim)] | |
34 | _RimPower("Rim Power", Range(0,20)) = 20 | |
35 | [HDR]_RimColor("Rim Color Snow", Color) = (0.5,0.5,0.5,1) | |
36 | } | |
37 | ||
38 | SubShader{ | |
39 | Tags{ "RenderType" = "Opaque" } | |
40 | LOD 200 | |
41 | ||
42 | CGPROGRAM | |
43 | ||
44 | ||
45 | // custom lighting function that uses a texture ramp based | |
46 | // on angle between light direction and normal | |
47 | #pragma surface surf ToonRamp vertex:vert addshadow nolightmap tessellate:tessDistance fullforwardshadows | |
48 | #pragma target 4.0 | |
49 | #pragma require tessellation tessHW | |
50 | #include "Tessellation.cginc" | |
51 | ||
52 | float4 _ShadowColor; | |
53 | ||
54 | inline half4 LightingToonRamp(SurfaceOutput s, half3 lightDir, half atten) | |
55 | { | |
56 | #ifndef USING_DIRECTIONAL_LIGHT | |
57 | lightDir = normalize(lightDir); | |
58 | #endif | |
59 | half4 c; | |
60 | c.rgb = s.Albedo * _LightColor0.rgb * (atten + (_ShadowColor * (1-atten))); | |
61 | c.a = 0; | |
62 | return c; | |
63 | } | |
64 | uniform float3 _Position; | |
65 | uniform sampler2D _GlobalEffectRT; | |
66 | uniform float _OrthographicCamSize; | |
67 | ||
68 | float _Tess; | |
69 | float _MaxTessDistance; | |
70 | ||
71 | float CalcDistanceTessFactor(float4 vertex, float minDist, float maxDist, float tess) | |
72 | { | |
73 | float3 worldPosition = mul(unity_ObjectToWorld, vertex).xyz; | |
74 | float dist = distance(worldPosition, _WorldSpaceCameraPos); | |
75 | float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0); | |
76 | return f * tess; | |
77 | } | |
78 | ||
79 | float4 DistanceBasedTess(float4 v0, float4 v1, float4 v2, float minDist, float maxDist, float tess) | |
80 | { | |
81 | float3 f; | |
82 | f.x = CalcDistanceTessFactor(v0, minDist, maxDist, tess); | |
83 | f.y = CalcDistanceTessFactor(v1, minDist, maxDist, tess); | |
84 | f.z = CalcDistanceTessFactor(v2, minDist, maxDist, tess); | |
85 | ||
86 | return UnityCalcTriEdgeTessFactors(f); | |
87 | } | |
88 | ||
89 | float4 tessDistance(appdata_full v0, appdata_full v1, appdata_full v2) | |
90 | { | |
91 | float minDist = 10.0; | |
92 | float maxDist = _MaxTessDistance; | |
93 | ||
94 | return DistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, minDist, maxDist, _Tess); | |
95 | } | |
96 | ||
97 | sampler2D _MainTex, _Noise, _SparkleNoise; | |
98 | float4 _Color, _RimColor; | |
99 | float _RimPower; | |
100 | float _SnowTextureScale, _NoiseScale; | |
101 | float _SnowHeight, _SnowPathStrength; | |
102 | float4 _PathColorIn, _PathColorOut; | |
103 | float _PathBlending; | |
104 | float _NoiseWeight; | |
105 | float _SparkleScale, _SparkCutoff; | |
106 | float _SnowTextureOpacity; | |
107 | ||
108 | struct Input { | |
109 | float2 uv_MainTex : TEXCOORD0; | |
110 | float3 worldPos; // world position built-in value | |
111 | float3 viewDir;// view direction built-in value we're using for rimlight | |
112 | }; | |
113 | ||
114 | void vert(inout appdata_full v) | |
115 | { | |
116 | ||
117 | float3 worldPosition = mul(unity_ObjectToWorld, v.vertex).xyz; | |
118 | // Effects RenderTexture Reading | |
119 | float2 uv = worldPosition.xz - _Position.xz; | |
120 | uv = uv / (_OrthographicCamSize * 2); | |
121 | uv += 0.5; | |
122 | float4 RTEffect = tex2Dlod(_GlobalEffectRT, float4(uv, 0, 0)); | |
123 | ||
124 | // smoothstep edges to prevent bleeding | |
125 | RTEffect *= smoothstep(0.99, 0.9, uv.x) * smoothstep(0.99, 0.9,1- uv.x); | |
126 | RTEffect *= smoothstep(0.99, 0.9, uv.y) * smoothstep(0.99, 0.9,1- uv.y); | |
127 | ||
128 | // Snow Noise in worldSpace | |
129 | float SnowNoise = tex2Dlod(_Noise, float4(worldPosition.xz * _NoiseScale, 0, 0)); | |
130 | ||
131 | // move vertices up where snow is, and where there is no path | |
132 | v.vertex.xyz += normalize(v.normal) *(_SnowHeight + (SnowNoise * _NoiseWeight)) * saturate(1-RTEffect.g * _SnowPathStrength); | |
133 | ||
134 | } | |
135 | ||
136 | ||
137 | ||
138 | void surf(Input IN, inout SurfaceOutput o) { | |
139 | // Effects RenderTexture Reading | |
140 | float2 uv = IN.worldPos.xz - _Position.xz; | |
141 | uv /= (_OrthographicCamSize * 2); | |
142 | uv += 0.5; | |
143 | ||
144 | float4 effect = tex2D(_GlobalEffectRT, float2 (uv.x, uv.y)); | |
145 | effect *= smoothstep(0.99, 0.9, uv.x) * smoothstep(0.99, 0.9,1- uv.x); | |
146 | effect *= smoothstep(0.99, 0.9, uv.y) * smoothstep(0.99, 0.9,1- uv.y); | |
147 | ||
148 | // worldspace Noise texture | |
149 | float3 noisetexture = tex2D(_Noise, IN.worldPos.zx * _NoiseScale); | |
150 | ||
151 | // worldspace Snow texture | |
152 | float3 snowtexture = tex2D(_MainTex, IN.worldPos.zx * _SnowTextureScale); | |
153 | ||
154 | // rim light for snow, blending in the noise texture | |
155 | half rim = 1.0 - dot(normalize(IN.viewDir), o.Normal) * noisetexture; | |
156 | float3 coloredRim = _RimColor * pow(rim, _RimPower); | |
157 | ||
158 | //lerp between snow color and snow texture | |
159 | float3 mainColors = lerp(_Color,snowtexture * _Color, _SnowTextureOpacity); | |
160 | //lerp the colors using the RT effect path | |
161 | float3 path = lerp(_PathColorOut * effect.g,_PathColorIn, saturate(effect.g * _PathBlending)); | |
162 | o.Albedo = lerp(mainColors,path, saturate(effect.g)); | |
163 | ||
164 | // sparkles in worldspace | |
165 | float sparklesStatic = tex2D(_SparkleNoise, IN.worldPos.xz * _SparkleScale).r; | |
166 | // cutoff and where there is no path | |
167 | float cutoffSparkles = step(_SparkCutoff,sparklesStatic *(1- saturate(effect.g))); | |
168 | // add a glow and sparkles on the snow | |
169 | o.Emission = coloredRim + (cutoffSparkles * 4) ; | |
170 | ||
171 | ||
172 | } | |
173 | ENDCG | |
174 | ||
175 | } | |
176 | ||
177 | Fallback "Diffuse" | |
178 | } |