SHOW:
|
|
- or go back to the newest paste.
1 | Shader "Toon/Lit Snow Buildup" { | |
2 | Properties{ | |
3 | _Color("Main Color", Color) = (0.5,0.5,0.5,1) | |
4 | _MainTex("Base (RGB)", 2D) = "white" {} | |
5 | _Ramp("Toon Ramp (RGB)", 2D) = "gray" {} | |
6 | _SnowRamp("Snow Toon Ramp (RGB)", 2D) = "gray" {} | |
7 | _SnowAngle("Angle of snow buildup", Vector) = (0,1,0) | |
8 | _SnowColor("Snow Base Color", Color) = (0.5,0.5,0.5,1) | |
9 | _TColor("Snow Top Color", Color) = (0.5,0.5,0.5,1) | |
10 | _RimColor("Snow Rim Color", Color) = (0.5,0.5,0.5,1) | |
11 | _RimPower("Snow Rim Power", Range(0,4)) = 3 | |
12 | _SnowSize("Snow Amount", Range(-2,2)) = 1 | |
13 | _Height("Snow Height", Range(0,0.2)) = 0.1 | |
14 | ||
15 | ||
16 | ||
17 | } | |
18 | ||
19 | SubShader{ | |
20 | Tags{ "RenderType" = "Opaque" } | |
21 | LOD 200 | |
22 | Cull Off | |
23 | CGPROGRAM | |
24 | ||
25 | #pragma surface surf ToonRamp vertex:disp addshadow | |
26 | sampler2D _Ramp; | |
27 | ||
28 | // custom lighting function that uses a texture ramp based | |
29 | // on angle between light direction and normal | |
30 | #pragma lighting ToonRamp exclude_path:prepass | |
31 | inline half4 LightingToonRamp(SurfaceOutput s, half3 lightDir, half atten) | |
32 | { | |
33 | #ifndef USING_DIRECTIONAL_LIGHT | |
34 | lightDir = normalize(lightDir); | |
35 | #endif | |
36 | ||
37 | half d = dot(s.Normal, lightDir)*0.5 + 0.5; | |
38 | half3 ramp = tex2D(_Ramp, float2(d,d)).rgb; | |
39 | ||
40 | half4 c; | |
41 | c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2); | |
42 | c.a = 0; | |
43 | return c; | |
44 | } | |
45 | ||
46 | ||
47 | sampler2D _MainTex; | |
48 | sampler2D _SnowRamp; | |
49 | ||
50 | float4 _Color; | |
51 | float4 _SnowColor; | |
52 | float4 _TColor; | |
53 | float4 _SnowAngle; | |
54 | float4 _RimColor; | |
55 | ||
56 | float _SnowSize; | |
57 | float _Height; | |
58 | float _RimPower; | |
59 | ||
60 | struct Input { | |
61 | float2 uv_MainTex : TEXCOORD0; | |
62 | float3 worldPos; | |
63 | float3 viewDir; | |
64 | float3 lightDir; | |
65 | ||
66 | }; | |
67 | ||
68 | struct appdata { | |
69 | float4 vertex : POSITION; | |
70 | float3 normal : NORMAL; | |
71 | }; | |
72 | ||
73 | void disp(inout appdata_full v, out Input o) | |
74 | { | |
75 | UNITY_INITIALIZE_OUTPUT(Input, o); | |
76 | o.lightDir = WorldSpaceLightDir(v.vertex); // light direction for snow ramp | |
77 | float4 snowC = mul(_SnowAngle , unity_ObjectToWorld); // snow direction convertion to worldspace | |
78 | if (dot(v.normal, snowC.xyz) >= _SnowSize ) { | |
79 | v.vertex.xyz += v.normal * _Height;// scale vertices along normal | |
80 | } | |
81 | ||
82 | } | |
83 | ||
84 | void surf(Input IN, inout SurfaceOutput o) { | |
85 | ||
86 | float3 localPos = (IN.worldPos - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz); // local position for snow color blend | |
87 | half d = dot(o.Normal, IN.lightDir)*0.5 + 0.5; // light value for snow toon ramp | |
88 | half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; // main texture | |
89 | half3 rampS = tex2D(_SnowRamp, float2(d, d)).rgb; // snow toon ramp | |
90 | o.Albedo = c.rgb * _Color;// base color | |
91 | half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal)); // rimlight | |
92 | if (dot( o.Normal, _SnowAngle.xyz) >= _SnowSize -0.4) { // if dot product result is higher than snow amount, we turn it into snow | |
93 | o.Albedo = (lerp(_SnowColor * rampS, _TColor * rampS, saturate(localPos.y))); // blend base snow with top snow based on position | |
94 | o.Emission = _RimColor.rgb *pow(rim, _RimPower);// add glow rimlight to snow | |
95 | } | |
96 | o.Alpha = c.a; | |
97 | } | |
98 | ENDCG | |
99 | ||
100 | } | |
101 | ||
102 | Fallback "Diffuse" | |
103 | } |