Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

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,960
    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,960
    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.