Search Unity

Cutout with Soft Edge / Cutout Bumped Specular

Discussion in 'Shaders' started by bog-imp, Sep 5, 2012.

  1. bog-imp

    bog-imp

    Joined:
    Jul 25, 2012
    Posts:
    43
    On http://wiki.unity3d.com/index.php/Transparent_Cutout_Soft_Edge_Unlit_Texture_Blend
    I found solution that resolve problem with Soft Edge using two pass, and resolve many problems with render type,
    and receive light.

    So i srtart working on my Shader: Cutout Bumped Specular
    Code (csharp):
    1.  
    2. Shader "TEST/Cutout Bumped Specular"
    3. {
    4. Properties {
    5.     _Color ("Main Color", Color) = (1,1,1,1)
    6.     _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 0)
    7.     _Shininess ("Shininess", Range (0.01, 1)) = 0.078125
    8.     _MainTex ("Base (RGB) TransGloss (A)", 2D) = "white" {}
    9.     _BumpMap ("Normalmap", 2D) = "bump" {}
    10.     _SpecMap ("Specmap", 2D) = "white" {}
    11.     _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    12. }
    13.  
    14. SubShader {
    15.     Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    16.     LOD 400
    17.    
    18. CGPROGRAM
    19. // Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it does not contain a surface program or both vertex and fragment programs.
    20. #pragma exclude_renderers gles
    21. #pragma surface surf BlinnPhong2 alphatest:_Cutoff
    22. #pragma exclude_renderers flash
    23.  
    24. sampler2D _MainTex;
    25. sampler2D _BumpMap;
    26. sampler2D _SpecMap;
    27. fixed4 _Color;
    28. half _Shininess;
    29.  
    30. struct SurfaceOutput2 {
    31.     fixed3 Albedo;
    32.     fixed3 Normal;
    33.     fixed3 Emission;
    34.     half Specular;
    35.     half3 GlossColor;
    36.     fixed Gloss;
    37.     fixed Alpha;
    38. };
    39.  
    40.  
    41. // NOTE: some intricacy in shader compiler on some GLES2.0 platforms (iOS) needs 'viewDir'  'h'
    42. // to be mediump instead of lowp, otherwise specular highlight becomes too bright.
    43. inline fixed4 LightingBlinnPhong2 (SurfaceOutput2 s, fixed3 lightDir, half3 viewDir, fixed atten)
    44. {
    45.     half3 h = normalize (lightDir + viewDir);
    46.    
    47.     fixed diff = max (0, dot (s.Normal, lightDir));
    48.    
    49.     float nh = max (0, dot (s.Normal, h));
    50.     float spec = pow (nh, s.Specular*256.0) * s.GlossColor;
    51.    
    52.     fixed4 c;
    53.     c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * s.Gloss * spec) * (atten * 2);
    54.     c.a = s.Alpha + _LightColor0.a * _SpecColor.a * spec * atten;
    55.     return c;
    56. }
    57.  
    58. inline fixed4 LightingBlinnPhong2_PrePass (SurfaceOutput2 s, half4 light)
    59. {
    60.     fixed spec = light.a * s.Gloss;
    61.     fixed4 c;
    62.     c.rgb = (s.Albedo * light.rgb + light.rgb * s.GlossColor * _SpecColor.rgb * spec);
    63.     c.a = s.Alpha + spec * _SpecColor.a;
    64.     return c;
    65. }
    66.  
    67.  
    68. struct Input {
    69.     float2 uv_MainTex;
    70.     float2 uv_BumpMap;
    71. };
    72.  
    73. void surf (Input IN, inout SurfaceOutput2 o) {
    74.     fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    75.     fixed4 spec = tex2D(_SpecMap, IN.uv_MainTex);
    76.     o.Albedo = tex.rgb * _Color.rgb;
    77.     o.Gloss = tex.a;
    78.     o.GlossColor = spec.rgb;
    79.     o.Alpha = tex.a * _Color.a;
    80.     o.Specular = _Shininess;
    81.     o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    82. }
    83. ENDCG
    84. }
    85.  
    86. FallBack "Transparent/Cutout/VertexLit"
    87. }
    88.  
    89.  
    90.  

    But the main problem i can't add second pass like in http://wiki.unity3d.com/index.php/Transparent_Cutout_Soft_Edge_Unlit_Texture_Blend for Soft Edge, because i can't split proper clip.

    So how i can do that?
    Thank you for your help.
     
  2. dogzerx2

    dogzerx2

    Joined:
    Dec 27, 2009
    Posts:
    3,971
    Have you solved this? It would help me with my hair modelling endeavour :p
     
  3. Farfarer

    Farfarer

    Joined:
    Aug 17, 2010
    Posts:
    2,249
    This is what I use for my hair;

    Code (csharp):
    1. Shader "Exploration/Hair Soft Edge Surface" {
    2.     Properties {
    3.         _Color ("Main Color", Color) = (1,1,1,1)
    4.         _MainTex ("Diffuse (RGB) Alpha (A)", 2D) = "gray" {}
    5.         _SpecularTex ("Specular (R) Gloss (G) Null (B)", 2D) = "gray" {}
    6.         _BumpMap ("Normal (Normal)", 2D) = "bump" {}
    7.         _AnisoDirection ("Anisotropic Direction (RGB) Anisotropic Mask (A)", 2D) = "bump" {}
    8.         _AnisoOffset ("Anisotropic Highlight Offset", Range(-0.5,0.5)) = -0.2
    9.         _Cutoff ("Alpha Cut-Off Threshold", Range(0,1)) = 0.5
    10.         _Fresnel ("Fresnel Value", Float) = 0.028
    11.     }
    12.  
    13.     SubShader {
    14.         Tags { "RenderType" = "TransparentCutout" }
    15.  
    16.         CGPROGRAM
    17.             #pragma surface surf ExplorationSoftHair fullforwardshadows exclude_path:prepass nolightmap nodirlightmap
    18.             #pragma target 3.0
    19.  
    20.             struct SurfaceOutputHair {
    21.                 fixed3 Albedo;
    22.                 fixed Alpha;
    23.                 fixed3 AnisoDir;
    24.                 fixed3 Normal;
    25.                 fixed2 Specular;
    26.                 fixed3 Emission;
    27.             };
    28.  
    29.             struct Input
    30.             {
    31.                 float2 uv_MainTex;
    32.             };
    33.            
    34.             sampler2D _MainTex, _SpecularTex, _BumpMap, _AnisoDirection;
    35.             float _Cutoff, _AnisoOffset, _Fresnel;
    36.                
    37.             void surf (Input IN, inout SurfaceOutputHair o)
    38.             {
    39.                 float4 albedo = tex2D(_MainTex, IN.uv_MainTex);
    40.                 clip(albedo.a - _Cutoff);
    41.                
    42.                 o.Albedo = albedo.rgb;
    43.                 o.Alpha = albedo.a;
    44.                 o.AnisoDir = tex2D(_AnisoDirection, IN.uv_MainTex).rgb * 2 - 1;
    45.                 o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
    46.                 o.Specular = tex2D(_SpecularTex, IN.uv_MainTex).rg;
    47.                
    48.                 // Stop DX11 complaining.
    49.                 o.Emission = fixed3(0.0,0.0,0.0);
    50.             }
    51.  
    52.             inline fixed4 LightingExplorationSoftHair (SurfaceOutputHair s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    53.             {
    54.                 viewDir = normalize(viewDir);
    55.                 lightDir = normalize(lightDir);
    56.                 s.Normal = normalize(s.Normal);
    57.                 float NdotL = dot(s.Normal, lightDir);
    58.                 float3 h = normalize(lightDir + viewDir);
    59.                 float VdotH = dot( viewDir, h );
    60.  
    61.                 float fresnel = pow( 1.0 - VdotH, 5.0 );
    62.                 fresnel += _Fresnel * ( 1.0 - fresnel );
    63.                 float aniso = max(0, sin(radians( (dot(normalize(s.Normal + s.AnisoDir), h) + _AnisoOffset) * 180 ) ));
    64.                 float spec = pow( aniso, s.Specular.g * 128 ) * s.Specular.r * fresnel;
    65.                
    66.                 fixed4 c;
    67.                 c.rgb = (s.Albedo * saturate(NdotL) * atten * _LightColor0.rgb + (spec * atten * _LightColor0.rgb) ) * 2;
    68.                 c.a = s.Alpha;
    69.                
    70.                 return c;
    71.             }
    72.         ENDCG
    73.  
    74.         ZWrite Off
    75.  
    76.         CGPROGRAM
    77.             #pragma surface surf ExplorationSoftHair fullforwardshadows exclude_path:prepass nolightmap nodirlightmap decal:blend
    78.             #pragma target 3.0
    79.  
    80.             struct SurfaceOutputHair {
    81.                 fixed3 Albedo;
    82.                 fixed Alpha;
    83.                 fixed3 AnisoDir;
    84.                 fixed3 Normal;
    85.                 fixed2 Specular;
    86.                 fixed3 Emission;
    87.             };
    88.  
    89.             struct Input
    90.             {
    91.                 float2 uv_MainTex;
    92.             };
    93.            
    94.             sampler2D _MainTex, _SpecularTex, _BumpMap, _AnisoDirection;
    95.             float _Cutoff, _AnisoOffset, _Fresnel;
    96.                
    97.             void surf (Input IN, inout SurfaceOutputHair o)
    98.             {
    99.                 float4 albedo = tex2D(_MainTex, IN.uv_MainTex);
    100.                 clip(-(albedo.a - _Cutoff));
    101.                
    102.                 o.Albedo = albedo.rgb;
    103.                 o.Alpha = albedo.a;
    104.                 o.AnisoDir = tex2D(_AnisoDirection, IN.uv_MainTex).rgb * 2 - 1;
    105.                 o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
    106.                 o.Specular = tex2D(_SpecularTex, IN.uv_MainTex).rg;
    107.                
    108.                 // Stop DX11 complaining.
    109.                 o.Emission = fixed3(0.0,0.0,0.0);
    110.             }
    111.  
    112.             inline fixed4 LightingExplorationSoftHair (SurfaceOutputHair s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    113.             {
    114.                 viewDir = normalize(viewDir);
    115.                 lightDir = normalize(lightDir);
    116.                 s.Normal = normalize(s.Normal);
    117.                 float NdotL = dot(s.Normal, lightDir);
    118.                 float3 h = normalize(lightDir + viewDir);
    119.                 float VdotH = dot( viewDir, h );
    120.  
    121.                 float fresnel = pow( 1.0 - VdotH, 5.0 );
    122.                 fresnel += _Fresnel * ( 1.0 - fresnel );
    123.                 float aniso = max(0, sin(radians( (dot(normalize(s.Normal + s.AnisoDir), h) + _AnisoOffset) * 180 ) ));
    124.                 float spec = pow( aniso, s.Specular.g * 128 ) * s.Specular.r * fresnel;
    125.                
    126.                 fixed4 c;
    127.                 c.rgb = (s.Albedo * saturate(NdotL) * atten * _LightColor0.rgb + (spec * atten * _LightColor0.rgb) ) * 2;
    128.                 c.a = s.Alpha;
    129.                
    130.                 return c;
    131.             }
    132.         ENDCG
    133.     }
    134.     FallBack "Transparent/Cutout/VertexLit"
    135. }
    It's expensive, though. I'm not sure I'd recommend using it in a real game.

    I worked up a cheaper version of it here, but the quality isn't quite as good.
    Code (csharp):
    1.  
    2. Shader "Exploration/Hair Soft Edge Surface ZPrimed" {
    3.     Properties {
    4.         _Color ("Main Color", Color) = (1,1,1,1)
    5.         _MainTex ("Diffuse (RGB) Alpha (A)", 2D) = "gray" {}
    6.         _SpecularTex ("Specular (R) Gloss (G) Null (B)", 2D) = "gray" {}
    7.         _BumpMap ("Normal (Normal)", 2D) = "bump" {}
    8.         _AnisoDirection ("Anisotropic Direction (RGB) Anisotropic Mask (A)", 2D) = "bump" {}
    9.         _AnisoOffset ("Anisotropic Highlight Offset", Range(-0.5,0.5)) = -0.2
    10.         _Cutoff ("Alpha Cut-Off Threshold", Range(0,1)) = 0.5
    11.         _Fresnel ("Fresnel Value", Float) = 0.028
    12.     }
    13.  
    14.     SubShader {
    15.         Tags { "RenderType" = "Opaque" "Queue" = "Geometry"}
    16.  
    17.         Pass {
    18.             Name "Depth"
    19.             Tags {"LightMode" = "Always"}
    20.             ColorMask 0
    21.  
    22.             CGPROGRAM
    23.                 #pragma vertex vert
    24.                 #pragma fragment frag
    25.                 #pragma fragmentoption ARB_precision_hint_fastest
    26.  
    27.                 #include "UnityCG.cginc"
    28.  
    29.                 struct appdata {
    30.                     float4 vertex : POSITION;
    31.                     float4 texcoord : TEXCOORD0;
    32.                 };
    33.  
    34.                 struct v2f
    35.                 {
    36.                     float4  pos : SV_POSITION;
    37.                     float2  uv : TEXCOORD0;
    38.                 };
    39.  
    40.                 float4 _MainTex_ST;
    41.  
    42.                 v2f vert (appdata v)
    43.                 {
    44.                     v2f o;
    45.                     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    46.                     o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    47.                     return o;
    48.                 }
    49.  
    50.                 sampler2D _MainTex;
    51.                 float _Cutoff;
    52.  
    53.                 fixed4 frag(v2f IN) : COLOR
    54.                 {
    55.                     fixed alpha = tex2D(_MainTex, IN.uv).a;
    56.                     clip(alpha - _Cutoff);
    57.                     return fixed4(0.0,0.0,0.0,0.0);
    58.                 }
    59.             ENDCG
    60.         }
    61.  
    62.         ZWrite Off
    63.  
    64.         Blend SrcAlpha OneMinusSrcAlpha
    65.  
    66.         CGPROGRAM
    67.             #pragma surface surf ExplorationSoftHair fullforwardshadows exclude_path:prepass nolightmap nodirlightmap
    68.             #pragma target 3.0
    69.  
    70.             struct SurfaceOutputHair {
    71.                 fixed3 Albedo;
    72.                 fixed Alpha;
    73.                 fixed3 AnisoDir;
    74.                 fixed3 Normal;
    75.                 fixed2 Specular;
    76.                 fixed3 Emission;
    77.             };
    78.  
    79.             struct Input
    80.             {
    81.                 float2 uv_MainTex;
    82.             };
    83.            
    84.             sampler2D _MainTex, _SpecularTex, _BumpMap, _AnisoDirection;
    85.             float _Cutoff, _AnisoOffset, _Fresnel;
    86.                
    87.             void surf (Input IN, inout SurfaceOutputHair o)
    88.             {
    89.                 float4 albedo = tex2D(_MainTex, IN.uv_MainTex);
    90.                 o.Albedo = albedo.rgb;
    91.                 o.Alpha = albedo.a;
    92.                 o.AnisoDir = tex2D(_AnisoDirection, IN.uv_MainTex).rgb * 2 - 1;
    93.                 o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_MainTex));
    94.                 o.Specular = tex2D(_SpecularTex, IN.uv_MainTex).rg;
    95.                
    96.                 // Stop DX11 complaining.
    97.                 o.Emission = fixed3(0.0,0.0,0.0);
    98.             }
    99.  
    100.             inline fixed4 LightingExplorationSoftHair (SurfaceOutputHair s, fixed3 lightDir, fixed3 viewDir, fixed atten)
    101.             {
    102.                 viewDir = normalize(viewDir);
    103.                 lightDir = normalize(lightDir);
    104.                 s.Normal = normalize(s.Normal);
    105.                 float NdotL = dot(s.Normal, lightDir);
    106.                 float3 h = normalize(lightDir + viewDir);
    107.                 float VdotH = dot( viewDir, h );
    108.  
    109.                 float fresnel = pow( 1.0 - VdotH, 5.0 );
    110.                 fresnel += _Fresnel * ( 1.0 - fresnel );
    111.                 float aniso = max(0, sin(radians( (dot(normalize(s.Normal + s.AnisoDir), h) + _AnisoOffset) * 180 ) ));
    112.                
    113.                 float spec = pow( aniso, s.Specular.g * 128 ) * s.Specular.r * fresnel;
    114.  
    115.                 #if !defined(UNITY_PASS_FORWARDBASE)
    116.                     // Make the resulting value black where the alpha is.
    117.                     // Otherwise it blends through on transparent parts.
    118.                     // Not required for forward base - only forwardadd.
    119.                     atten *= s.Alpha;
    120.                 #endif
    121.                
    122.                 fixed4 c;
    123.                 c.rgb = ( ((s.Albedo * _LightColor0.rgb) * (saturate(NdotL) * atten)) + ((spec * atten) * _LightColor0.rgb) ) * 2;
    124.                 c.a = s.Alpha;
    125.                
    126.                 return c;
    127.             }
    128.         ENDCG
    129.     }
    130.     FallBack "Transparent/Cutout/VertexLit"
    131. }
    132.  
    Supports anisotropic highlights using a flow map, normal, specular, gloss and fresnel falloff.
     
    Last edited: Apr 25, 2013
    Mehrdad995, ATate, Luckymouse and 5 others like this.
  4. dogzerx2

    dogzerx2

    Joined:
    Dec 27, 2009
    Posts:
    3,971
    Whoa nice!!!!! I'll try it out right now!
     
  5. diegzumillo

    diegzumillo

    Joined:
    Jul 26, 2010
    Posts:
    418
    Just dropping by to thank farfarer for sharing that shader. I'm using it for something completely unrelated, I needed smooth transparency that received shadows :)
     
  6. nekitamotip

    nekitamotip

    Joined:
    Mar 19, 2017
    Posts:
    2
    @Farfarer

    Thank you SO MUCH for these shaders. They work a treat. I have been looking for a long time for a shader which allows transparent objects to receive shadows, but this is so much better than what I was hoping to get. Shadows, Fesnel... amazing! Thank you, thank you, thank you!
     
    Jordi_Unitys likes this.
  7. Jordi_Unitys

    Jordi_Unitys

    Joined:
    Dec 15, 2016
    Posts:
    19
    Hey!How did you do to allow transparent objects to recieve shadow with @Farfarer shaders?
     
  8. zainoccess

    zainoccess

    Joined:
    Nov 25, 2021
    Posts:
    1
    Try This
     

    Attached Files:

    Rickshaw likes this.