Search Unity

Snow / up vector shader

Discussion in 'Shaders' started by copenhagenjazz, Apr 9, 2013.

  1. copenhagenjazz

    copenhagenjazz

    Joined:
    Oct 2, 2005
    Posts:
    45
    Hi

    I have been looking for a snow / up vector shader for quite some time but so far the only shader I have found was this; http://unitygems.com/noobs-guide-shaders-2/

    I tried to create this shader but it didnt seem to work in Unity 4 at all unfortunately.

    Do any of you good people have such a shader lying around or would you know how to get the linked shader working.

    Thanks in advance :)
     
  2. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    Code (csharp):
    1. Shader "Custom/SnowShader" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "white" {}
    4.         _Bump ("Bump", 2D) = "bump" {}
    5.         _Snow ("Snow Level", Range(0,1) ) = 0
    6.         _SnowColor ("Snow Color", Color) = (1.0,1.0,1.0,1.0)
    7.         _SnowDirection ("Snow Direction", Vector) = (0,1,0)
    8.         _SnowDepth ("Snow Depth", Range(0,0.2)) = 0.1
    9.     }
    10.     SubShader {
    11.         Tags { "RenderType"="Opaque" }
    12.         LOD 200
    13.  
    14.         CGPROGRAM
    15.         #pragma surface surf Lambert vertex:vert
    16.  
    17.         sampler2D _MainTex;
    18.         sampler2D _Bump;
    19.         float _Snow;
    20.         float4 _SnowColor;
    21.         float4 _SnowDirection;
    22.         float _SnowDepth;
    23.  
    24.         struct Input {
    25.             float2 uv_MainTex;
    26.             float2 uv_Bump;
    27.             float3 worldNormal;
    28.             INTERNAL_DATA
    29.         };
    30.  
    31.         void vert (inout appdata_full v) {
    32.             //Convert the normal to world coortinates
    33.             float3 snormal = normalize(_SnowDirection.xyz);
    34.             float3 sn = mul((float3x3)_World2Object, snormal).xyz;
    35.  
    36.             if(dot(v.normal, sn) >= lerp(1,-1, (_Snow*2)/3))
    37.             {
    38.                v.vertex.xyz += normalize(sn + v.normal) * _SnowDepth * _Snow;
    39.             }
    40.         }
    41.  
    42.         void surf (Input IN, inout SurfaceOutput o) {
    43.             half4 c = tex2D (_MainTex, IN.uv_MainTex);
    44.             o.Normal = UnpackNormal (tex2D (_Bump, IN.uv_Bump));
    45.             if(dot(WorldNormalVector(IN, o.Normal), _SnowDirection.xyz)>=lerp(1,-1,_Snow))
    46.             {
    47.                 o.Albedo = _SnowColor.rgb;
    48.             }
    49.             else {
    50.                 o.Albedo = c.rgb;
    51.             }
    52.             o.Alpha = 1;
    53.         }
    54.         ENDCG
    55.     }
    56.     FallBack "Diffuse"
    57. }
     
    AttilaZold likes this.
  3. copenhagenjazz

    copenhagenjazz

    Joined:
    Oct 2, 2005
    Posts:
    45
    James youre the man! Thanks a lot :)

    How much would it complicate matters if I instead of snow wanted another texture (w. normalmap) applied? IE pebbles/sand covering a rock mesh?
     
  4. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    Not much. I did this a while back based on the same tutorial.
    Here's the shader with normalmapped texture blending instead of color blending:

    Code (csharp):
    1.  
    2. Shader "Custom/BlendSamplersByDirection" {
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.         _MainBump ("MainBump", 2D) = "bump" {}
    6.         _LayerTex ("Layer (RGB)", 2D) = "white" {}
    7.         _LayerBump ("LayerBump", 2D) ="bump" {}
    8.         _LayerStrength ("Layer Strength", Range(0, 1)) = 0
    9.         _LayerDirection ("Layer Direction", Vector) = (0, 1, 0)
    10.         _LayerDepth ("Layer Depth", Range(0, 0.005)) = 0.0005
    11.     }
    12.    
    13.     SubShader {
    14.         Tags { "RenderType"="Opaque" }
    15.         LOD 200
    16.        
    17.         CGPROGRAM
    18.         #pragma target 3.0
    19.         #pragma surface surf Lambert vertex:vert
    20.  
    21.         sampler2D _MainTex;
    22.         sampler2D _MainBump;
    23.         sampler2D _LayerTex;
    24.         sampler2D _LayerBump;
    25.         float _LayerStrength;
    26.         float3 _LayerDirection;
    27.         float _LayerDepth;
    28.  
    29.         struct Input {
    30.             float2 uv_MainTex;
    31.             float2 uv_MainBump;
    32.             float2 uv_LayerTex;
    33.             float2 uv_LayerBump;
    34.             float3 worldNormal;
    35.             INTERNAL_DATA
    36.         };
    37.        
    38.         void vert (inout appdata_full v) {
    39.             // Convert the normal to world coordinates/world space
    40.             float3 sn = mul((float3x3)_World2Object, _LayerDirection);
    41.            
    42.             if (dot(v.normal, sn.xyz) >= lerp(1, -1, (_LayerStrength * 2) / 3))
    43.             {
    44.                 v.vertex.xyz += (sn.xyz + v.normal) * _LayerDepth * _LayerStrength;
    45.             }
    46.         }
    47.  
    48.         void surf (Input IN, inout SurfaceOutput o) {
    49.    
    50.             // Diffuse color of pixel
    51.             half4 mainDiffuse = tex2D(_MainTex, IN.uv_MainTex);
    52.             half4 layerDiffuse = tex2D(_LayerTex, IN.uv_LayerTex);
    53.            
    54.             // Normal vector of pixel
    55.             o.Normal = UnpackNormal(tex2D(_MainBump, IN.uv_MainBump));
    56.             half3 layerNormal = half3(0, 0, 0);
    57.            
    58.             // Snow mask
    59.             half sm = dot(WorldNormalVector(IN, o.Normal), _LayerDirection);
    60.             sm = pow(0.5 * sm + 0.5, 2.0);
    61.            
    62.             if (sm >= lerp(1, 0, _LayerStrength))
    63.             {
    64.                 o.Albedo = (layerDiffuse.rgb + 0.5 * mainDiffuse.rgb) * 0.75;
    65.                 layerNormal = UnpackNormal(tex2D(_LayerBump, IN.uv_LayerBump));
    66.                 o.Normal = normalize(o.Normal + layerNormal);
    67.             }
    68.             else
    69.             {
    70.                 o.Albedo = mainDiffuse.rgb;
    71.             }
    72.        
    73.             o.Alpha = mainDiffuse.a;
    74.         }
    75.         ENDCG
    76.     }
    77.     FallBack "Diffuse"
    78. }
    Though you should note the difference in the target version. I think I was forced to use SM 3.0 because of the 2 additional texture samplers.
     
    AttilaZold likes this.
  5. copenhagenjazz

    copenhagenjazz

    Joined:
    Oct 2, 2005
    Posts:
    45
    Marco; you too are the man! Thanks so much, it works great :)
     
    Last edited: Apr 10, 2013
  6. JesseCarpenter

    JesseCarpenter

    Joined:
    Nov 7, 2013
    Posts:
    5
    This is really cool, but could you blend this texture (snow/moss etc..) with a heightmap? That would make it look even nicer. :)
     
  7. 26PM

    26PM

    Joined:
    May 2, 2014
    Posts:
    7
    Awesome! It works perfectly for me. Thanks a lot.
     
  8. DarkTree

    DarkTree

    Joined:
    Mar 23, 2013
    Posts:
    239
    Realy helpfull thanks guys!
     
  9. MorbiusTepes

    MorbiusTepes

    Joined:
    Nov 5, 2015
    Posts:
    4
    This is just the shader i was looking for. It is very fast on mobile. Because i'm a noob when it comes to shaders, I would like to ask if someone could modify this shader so it supports cutout, so even the trees would look good. That would be a lifesaver for me :)