Advertisement
Guest User

LitInteractiveSnow.shader

a guest
Mar 29th, 2019
1,399
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Shader "Toon/Lit Interactive 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.         _ToonRamp("Main Color", Color) = (0.5,0.5,0.5,1)
  8.         _Mask("Mask", 2D) = "white" {}// This mask prevents bleeding of the RT, make it white with a transparent edge around all sides, set to CLAMP, not repeat
  9.         [Space]
  10.         [Header(Tesselation)]
  11.         _MaxTessDistance("Max Tessellation Distance", Range(10,100)) = 50
  12.         _Tess("Tessellation", Range(1,32)) = 20
  13.         [Space]
  14.         [Header(Snow)]
  15.         _Color("Snow Color", Color) = (0.5,0.5,0.5,1)
  16.         _PathColor("Snow Path Color", Color) = (0.5,0.5,0.7,1)
  17.         _MainTex("Snow Texture", 2D) = "white" {}      
  18.         _SnowHeight("Snow Height", Range(0,2)) = 0.3
  19.         _SnowDepth("Snow Path Depth", Range(-2,2)) = 0.3
  20.         _EdgeColor("Snow Edge Color", Color) = (0.5,0.5,0.5,1)
  21.         _Edgewidth("Snow Edge Width", Range(0,0.2)) = 0.1
  22.         _SnowTextureOpacity("Snow Texture Opacity", Range(0,2)) = 0.3
  23.         _SnowTextureScale("Snow Texture Scale", Range(0,2)) = 0.3
  24.         [Space]
  25.         [Header(Sparkles)]
  26.         _SparkleScale("Sparkle Scale", Range(0,10)) = 10
  27.         _SparkCutoff("Sparkle Cutoff", Range(0,10)) = 0.1
  28.         _SparkleNoise("Sparkle Noise", 2D) = "gray" {}
  29.         [Space]
  30.         [Header(Extra Textures)]
  31.         _MainTexBase("Base Texture", 2D) = "white" {}
  32.         _Scale("Base Scale", Range(0,2)) = 1
  33.         [Space]
  34.         [Header(Rim)]
  35.         _BaseColor("Base Color", Color) = (0.5,0.5,0.5,1)
  36.         _RimPower("Rim Power", Range(0,20)) = 20
  37.         _RimColor("Rim Color Snow", Color) = (0.5,0.5,0.5,1)
  38.     }
  39.  
  40.         SubShader{
  41.         Tags{ "RenderType" = "Opaque" }
  42.         LOD 200
  43.  
  44.         CGPROGRAM
  45.  
  46.  
  47.             // custom lighting function that uses a texture ramp based
  48.             // on angle between light direction and normal
  49.     #pragma surface surf ToonRamp vertex:vert addshadow nolightmap tessellate:tessDistance fullforwardshadows
  50.     #pragma target 4.0
  51.     #pragma require tessellation tessHW
  52.     #include "Tessellation.cginc"
  53.             float4 _ToonRamp;
  54.             inline half4 LightingToonRamp(SurfaceOutput s, half3 lightDir, half atten)
  55.             {
  56.         #ifndef USING_DIRECTIONAL_LIGHT
  57.                 lightDir = normalize(lightDir);
  58.         #endif
  59.                 float d = dot(s.Normal, lightDir);         
  60.                 float3 ramp = smoothstep(0, d + 0.06, d) + _ToonRamp;
  61.  
  62.                 half4 c;
  63.                 c.rgb = s.Albedo * _LightColor0.rgb * (ramp) * (atten * 2);
  64.                 c.a = 0;
  65.                 return c;
  66.             }
  67.             uniform float3 _Position;
  68.             uniform sampler2D _GlobalEffectRT;
  69.             uniform float _OrthographicCamSize;
  70.  
  71.             float _Tess;
  72.             float _MaxTessDistance;
  73.             // big thanks to Cone Wars devs for explaining tesselation http://diary.conewars.com/tessellation-melt-shader-part-3/
  74.             float ColorCalcDistanceTessFactor(float4 vertex, float minDist, float maxDist, float tess, float4 color)
  75.             {
  76.                 float3 worldPosition = mul(unity_ObjectToWorld, vertex).xyz;
  77.                 float dist = distance(worldPosition, _WorldSpaceCameraPos);
  78.                 float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0);
  79.  
  80.                 if (color.r < 0.4) {
  81.                     f = 0.001;
  82.                 }
  83.                 return f * tess;
  84.             }
  85.  
  86.             float4 ColorDistanceBasedTess(float4 v0, float4 v1, float4 v2, float minDist, float maxDist, float tess, float4 v0c, float4 v1c, float4 v2c)
  87.             {
  88.                 float3 f;
  89.                 f.x = ColorCalcDistanceTessFactor(v0, minDist, maxDist, tess, v0c);
  90.                 f.y = ColorCalcDistanceTessFactor(v1, minDist, maxDist, tess, v1c);
  91.                 f.z = ColorCalcDistanceTessFactor(v2, minDist, maxDist, tess, v2c);
  92.  
  93.                 return UnityCalcTriEdgeTessFactors(f);
  94.             }
  95.  
  96.             float4 tessDistance(appdata_full v0, appdata_full v1, appdata_full v2)
  97.             {
  98.                 float minDist = 10.0;
  99.                 float maxDist = _MaxTessDistance;
  100.  
  101.                 return ColorDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, minDist, maxDist, _Tess, v0.color, v1.color, v2.color);
  102.             }
  103.  
  104.             sampler2D _MainTex, _MainTexBase, _Noise, _SparkleNoise;
  105.             float4 _Color, _RimColor;
  106.             float _RimPower;
  107.             float _Scale, _SnowTextureScale, _NoiseScale;
  108.             float4 _EdgeColor;
  109.             float _Edgewidth;
  110.             float _SnowHeight, _SnowDepth;
  111.             float4 _PathColor, _BaseColor;
  112.             sampler2D _Mask;
  113.             float _NoiseWeight;
  114.             float _SparkleScale, _SparkCutoff;
  115.             float _SnowTextureOpacity;
  116.  
  117.             struct Input {
  118.                 float2 uv_MainTex : TEXCOORD0;
  119.                 float3 worldPos; // world position built-in value
  120.                 float3 viewDir;// view direction built-in value we're using for rimlight
  121.                 float4 vertexColor : COLOR;
  122.                 float4 screenPos;// screen position built-in value
  123.             };
  124.  
  125.             void vert(inout appdata_full v)
  126.             {  
  127.                
  128.                 float3 worldPosition = mul(unity_ObjectToWorld, v.vertex).xyz;
  129.                 // Effects RenderTexture Reading
  130.                 float2 uv = worldPosition.xz - _Position.xz;
  131.                 uv = uv / (_OrthographicCamSize * 2);
  132.                 uv += 0.5;
  133.                 // Mask to prevent bleeding
  134.                 float mask = tex2Dlod(_Mask, float4(uv , 0,0)).a;
  135.                 float4 RTEffect = tex2Dlod(_GlobalEffectRT, float4(uv, 0, 0));
  136.                 RTEffect *= mask;
  137.                 // Snow Noise in worldSpace
  138.                 float SnowNoise = tex2Dlod(_Noise, float4(worldPosition.xz * _NoiseScale * 5, 0, 0));
  139.            
  140.                 // move vertices up where snow is
  141.                 v.vertex.xyz += normalize(v.normal) * (saturate((v.color.r * _SnowHeight) + (SnowNoise * _NoiseWeight * v.color.r)));
  142.                 // move down where there is a trail from the render texture particles
  143.                 v.vertex.xyz -= normalize(v.normal) * (RTEffect.g * saturate(v.color.r)) *  _SnowDepth;
  144.  
  145.             }
  146.  
  147.  
  148.  
  149.             void surf(Input IN, inout SurfaceOutput o) {
  150.                 // Effects RenderTexture Reading
  151.                 float2 uv = IN.worldPos.xz - _Position.xz;
  152.                 uv /= (_OrthographicCamSize * 2);
  153.                 uv += 0.5;
  154.  
  155.                 float mask = tex2D(_Mask, uv).a;
  156.                 float4 effect = tex2D(_GlobalEffectRT, float2 (uv.x, uv.y));
  157.                 effect *= mask;
  158.  
  159.                 // clamp (saturate) and increase(pow) the worldnormal value to use as a blend between the projected textures
  160.                 float3 blendNormal = saturate(pow(WorldNormalVector(IN, o.Normal) * 1.4,4));
  161.  
  162.                 // normal noise triplanar for x, y, z sides
  163.                 float3 xn = tex2D(_Noise, IN.worldPos.zy * _NoiseScale);
  164.                 float3 yn = tex2D(_Noise, IN.worldPos.zx * _NoiseScale);
  165.                 float3 zn = tex2D(_Noise, IN.worldPos.xy * _NoiseScale);
  166.  
  167.                 // lerped together all sides for noise texture
  168.                 float3 noisetexture = zn;
  169.                 noisetexture = lerp(noisetexture, xn, blendNormal.x);
  170.                 noisetexture = lerp(noisetexture, yn, blendNormal.y);
  171.  
  172.                 // triplanar for snow texture for x, y, z sides
  173.                 float3 xm = tex2D(_MainTex, IN.worldPos.zy * _SnowTextureScale);
  174.                 float3 zm = tex2D(_MainTex, IN.worldPos.xy * _SnowTextureScale);
  175.                 float3 ym = tex2D(_MainTex, IN.worldPos.zx * _SnowTextureScale);
  176.  
  177.                 // lerped together all sides for snow texture
  178.                 float3 snowtexture = zm;
  179.                 snowtexture = lerp(snowtexture, xm, blendNormal.x);
  180.                 snowtexture = lerp(snowtexture, ym, blendNormal.y);
  181.  
  182.                 // triplanar for base texture, x,y,z sides
  183.                 float3 x = tex2D(_MainTexBase, IN.worldPos.zy * _Scale);
  184.                 float3 y = tex2D(_MainTexBase, IN.worldPos.zx * _Scale);
  185.                 float3 z = tex2D(_MainTexBase, IN.worldPos.xy * _Scale);
  186.  
  187.                 // lerped together all sides for base texture
  188.                 float3 baseTexture = z;
  189.                 baseTexture = lerp(baseTexture, x, blendNormal.x);
  190.                 baseTexture = lerp(baseTexture, y, blendNormal.y);
  191.  
  192.                 // rim light for snow, blending in the noise texture
  193.                 half rim = 1.0 - dot((IN.viewDir), BlendNormals(o.Normal, noisetexture));
  194.  
  195.                
  196.                 // primary texture only on red vertex color with the noise texture
  197.                 float vertexColoredPrimary = step(0.6* noisetexture,IN.vertexColor.r);
  198.                 float3 snowTextureResult = vertexColoredPrimary * snowtexture;
  199.  
  200.                 // edge for primary texture
  201.                 float vertexColorEdge = (step((0.6 - _Edgewidth)* noisetexture,IN.vertexColor.r)) * (1 - vertexColoredPrimary);
  202.                 // edge for secondary texture
  203.  
  204.                 // basetexture only where there is no red vertex paint
  205.                 float3 baseTextureResult = baseTexture * (1 - (vertexColoredPrimary + vertexColorEdge));
  206.  
  207.                 // final albedo color by adding everything together
  208.                 float3 mainColors = (baseTextureResult *  _BaseColor) + ((snowTextureResult * _SnowTextureOpacity)+ (vertexColoredPrimary * _Color)) + (vertexColorEdge * _EdgeColor);
  209.                 //lerp the colors using the RT effect path
  210.                 o.Albedo = lerp(mainColors, _PathColor * effect.g, saturate(effect.g * 2 * vertexColoredPrimary));
  211.                
  212.                 // sparkles, static multiplied by a simple screenpos version
  213.                 float sparklesStatic = tex2D(_SparkleNoise, IN.uv_MainTex * _SparkleScale * 5) ;
  214.                 float sparklesResult = tex2D(_SparkleNoise, (IN.uv_MainTex * IN.screenPos) * _SparkleScale) * sparklesStatic;
  215.                 o.Albedo += step(_SparkCutoff, sparklesResult) *vertexColoredPrimary;
  216.    
  217.                 // add a glow on the snow part
  218.                 o.Emission = vertexColoredPrimary * _RimColor * pow(rim, _RimPower) ;
  219.  
  220.  
  221.             }
  222.             ENDCG
  223.  
  224.         }
  225.  
  226.             Fallback "Diffuse"
  227. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement