Search Unity

Receive shadows on normal's back in custom vert/frag shader

Discussion in 'Shaders' started by semoki, May 18, 2017.

  1. semoki

    semoki

    Joined:
    Feb 1, 2017
    Posts:
    2
    I wrote a vert/frag shader with the aim to have it render on front and back faces.
    While the front looks good, my problem is that I can't figure out how to obtain shadows on the back face from other objects in the scene (I mean to receiving them, not casting them).
    I'm sorry if the question is already been posted but I couldn't find anything similar.

    Code (CSharp):
    1. Shader "Custom/Double Sided"
    2. {
    3.    Properties
    4.    {
    5.       // front diffuse
    6.       _Color ("Front Diffuse color", Color) = (1,1,1,1)
    7.       _MainTex ("Front Diffuse", 2D) = "white" {}
    8.       _CutOff ("Front Alpha Cutoff", Range(0,1.1)) = 0
    9.       // front specular
    10.       _SpecColor ("Front Specular color", Color) = (0,0,0,0)
    11.       _SpecTex ("Front Specular texture", 2D) = "white" {}
    12.       _SpecIntensity ("Front Specular intensity", Range(0, 1)) = 1
    13.       _Shininess ("Front Specular sharpness", Range(0.01, 10)) = 1
    14.       // front others
    15.       _BumpMap ("Front Normal map", 2D) = "bump" {}
    16.       _Ao ("Front Ambient occlusion", 2D) = "white" {}
    17.  
    18.       // back diffuse
    19.       _BackColor ("Back Diffuse color", Color) = (1,1,1,1)
    20.       _BackMainTex ("Back Diffuse", 2D) = "white" {}
    21.       _BackCutOff ("Back Alpha Cutoff", Range(0,1.1)) = 0
    22.       // back specular
    23.       _BackSpecColor ("Back Specular color", Color) = (0,0,0,0)
    24.       _BackSpecTex ("Back Specular texture", 2D) = "white" {}
    25.       _BackSpecIntensity ("Back Specular intensity", Range(0, 1)) = 1
    26.       _BackShininess ("Back Specular sharpness", Range(0.01, 10)) = 1
    27.       // back others
    28.       _BackBumpMap ("Back Normal map", 2D) = "bump" {}
    29.       _BackAo ("Back Ambient occlusion", 2D) = "white" {}
    30.    }
    31.  
    32.    SubShader
    33.    {
    34.         Tags
    35.         {
    36.             "RenderType"="Opaque"
    37.             "PerformanceChecks"="False"
    38.         }
    39.         LOD 300
    40.  
    41.         //_____________________________________ front pass for ambient light and first light source
    42.         Pass
    43.         {
    44.             Tags { "LightMode" = "ForwardBase" }
    45.             Cull Back // render only front faces
    46.            
    47.             CGPROGRAM
    48.            
    49.             #pragma vertex vert
    50.             #pragma fragment frag
    51.             #pragma multi_compile_fwdbase
    52.             #pragma fragmentoption ARB_fog_exp2
    53.             #pragma fragmentoption ARB_precision_hint_fastest
    54.             #pragma target 3.0
    55.            
    56.             #include "UnityCG.cginc"
    57.             #include "AutoLight.cginc"
    58.  
    59.             // Unity-defined variables
    60.             uniform float4 _LightColor0; // color of light source (from "Lighting.cginc")
    61.            
    62.             // User-specified properties
    63.             uniform float4 _Color;
    64.             uniform sampler2D _MainTex;
    65.             uniform float4 _MainTex_ST;
    66.             uniform float4 _SpecColor;
    67.             uniform sampler2D _SpecTex;
    68.             uniform float4 _SpecTex_ST;
    69.             uniform float _SpecIntensity;
    70.             uniform float _Shininess;
    71.             uniform sampler2D _BumpMap;
    72.             uniform float4 _BumpMap_ST;
    73.             uniform sampler _Ao;
    74.             uniform float4 _Ao_ST;
    75.             uniform float _CutOff;
    76.            
    77.             struct vertexInput
    78.             {
    79.                 float4 vertex : POSITION;
    80.                 float3 normal : NORMAL;
    81.                 float2 texcoord : TEXCOORD0;
    82.                 float4 tangent: TANGENT;
    83.             };
    84.             struct vertex2frag
    85.             {
    86.                 float4 pos : SV_POSITION;
    87.                 float2 tex : TEXCOORD0;
    88.                 float4 posWorld: TEXCOORD1;
    89.                 float3 normalWorld: TEXCOORD2;
    90.                 float3 tangentWorld: TEXCOORD3;
    91.                 float3 binormalWorld: TEXCOORD4;
    92.                 LIGHTING_COORDS(5, 6)
    93.             };
    94.  
    95.             // Vertex Function
    96.             vertex2frag vert(vertexInput v)
    97.             {
    98.                 vertex2frag o;
    99.  
    100.                 o.tangentWorld = normalize(
    101.                     mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );    
    102.                 o.normalWorld = normalize(
    103.                     mul( float4( v.normal, 0.0 ), unity_WorldToObject ).xyz );
    104.                 o.binormalWorld = normalize(
    105.                     cross( o.normalWorld, o.tangentWorld )
    106.                     * v.tangent.w);
    107.                        
    108.                 o.posWorld = mul( unity_ObjectToWorld, v.vertex );
    109.                 o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    110.                 o.tex = v.texcoord;
    111.  
    112.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    113.                 return o;
    114.             }
    115.        
    116.             // Fragment Function
    117.             float4 frag(vertex2frag i) : SV_Target
    118.             {
    119.                 float3 viewDirection = normalize( _WorldSpaceCameraPos.xyz - i.posWorld.xyz );
    120.  
    121. //                float atten = lerp( // lerp based on type of light, directional or point/spot
    122. //                    1.0,
    123. //                    1 / length(_WorldSpaceLightPos0.xyz - i.posWorld.xyz),
    124. //                    ceil(_WorldSpaceLightPos0.w)
    125. //                );
    126.                 float atten = LIGHT_ATTENUATION(i);
    127.                 float3 lightDirection = lerp( // lerp based on type of light, directional or point/spot
    128.                     normalize( _WorldSpaceLightPos0.xyz ),
    129.                     normalize( _WorldSpaceLightPos0.xyz - i.posWorld.xyz ),
    130.                     ceil(_WorldSpaceLightPos0.w)
    131.                 );
    132.                
    133.                 // Texture Maps
    134.                 float4 tex = tex2D( _MainTex, i.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw );
    135.                 if(tex.a < _CutOff)
    136.                     discard;
    137.                 float4 texS = tex2D( _SpecTex, i.tex.xy * _SpecTex_ST.xy + _SpecTex_ST.zw );
    138.                 float4 texN = tex2D( _BumpMap, i.tex.xy * _BumpMap_ST.xy + _BumpMap_ST.zw );
    139.                 float4 texAo = tex2D( _Ao, i.tex.xy * _Ao_ST.xy + _Ao_ST.zw );
    140.  
    141.                 // unpackNormal Function
    142.                 float3 localCoords = float3(2.0 * texN.a - 1.0,
    143.                     2.0 * texN.g - 1.0, 0.0);
    144.                 localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
    145.                
    146.                 // Normal Transpose Matrix
    147.                 float3x3 local2WorldTranspose = float3x3(
    148.                     i.tangentWorld,
    149.                     i.binormalWorld,
    150.                     i.normalWorld
    151.                 );
    152.                
    153.                 // Calculate Normal Direction
    154.                 float3 normalDirection = normalize( mul( localCoords, local2WorldTranspose ) );
    155.                
    156.                 // Lighting
    157.                 float3 ambientLighting =
    158.                     UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb * tex.rgb;
    159.                 float3 diffuseReflection =
    160.                     atten * _LightColor0.rgb * _Color.rgb * tex.rgb
    161.                     * max(0, dot( normalDirection, lightDirection) );
    162.                 float3 specularReflection = lerp( // lerp based on what side is the light
    163.                     float3(0, 0, 0),
    164.                     atten * _LightColor0.rgb *
    165.                     (_SpecColor.rgb * texS.rgb * _SpecIntensity) *
    166.                     pow(max(0.0, dot(
    167.                         reflect(-lightDirection, normalDirection),
    168.                         viewDirection)), _Shininess * 100),
    169.                     floor(dot(normalDirection, lightDirection) + 1));
    170.  
    171.                 float4 finalLight = float4( (ambientLighting + diffuseReflection + specularReflection) * texAo.rgb, 1.0);
    172.                 return finalLight;
    173.             }
    174.        
    175.             ENDCG
    176.         }
    177.  
    178.         //_____________________________________ back pass for ambient light and first light source
    179.         Pass
    180.         {  
    181.             Tags { "LightMode" = "ForwardBase" }
    182.             Cull Front// render only back faces
    183.            
    184.             CGPROGRAM
    185.            
    186.             #pragma vertex vert
    187.             #pragma fragment frag
    188.             #pragma multi_compile_bckbase
    189.             #pragma fragmentoption ARB_fog_exp2
    190.             #pragma fragmentoption ARB_precision_hint_fastest
    191.             #pragma target 3.0
    192.  
    193.             #include "UnityCG.cginc"
    194.             #include "AutoLight.cginc"
    195.            
    196.             // Unity-defined variables
    197.             uniform float4 _LightColor0; // color of light source (from "Lighting.cginc")
    198.            
    199.             // User-specified properties
    200.             uniform float4 _BackColor;
    201.             uniform sampler2D _BackMainTex;
    202.             uniform float4 _BackMainTex_ST;
    203.             uniform float4 _BackSpecColor;
    204.             uniform sampler2D _BackSpecTex;
    205.             uniform float4 _BackSpecTex_ST;
    206.             uniform float _BackSpecIntensity;
    207.             uniform float _BackShininess;
    208.             uniform sampler2D _BackBumpMap;
    209.             uniform float4 _BackBumpMap_ST;
    210.             uniform sampler _BackAo;
    211.             uniform float4 _BackAo_ST;
    212.             uniform float _BackCutOff;
    213.            
    214.             struct vertexInput
    215.             {
    216.                 float4 vertex : POSITION;
    217.                 float3 normal : NORMAL;
    218.                 float2 texcoord : TEXCOORD0;
    219.                 float4 tangent: TANGENT;
    220.             };
    221.             struct vertex2frag
    222.             {
    223.                 float4 pos : SV_POSITION;
    224.                 float2 tex : TEXCOORD0;
    225.                 float4 posWorld: TEXCOORD1;
    226.                 float3 normalWorld: TEXCOORD2;
    227.                 float3 tangentWorld: TEXCOORD3;
    228.                 float3 binormalWorld: TEXCOORD4;
    229.                 LIGHTING_COORDS(5,6)
    230.             };
    231.  
    232.             // Vertex Function
    233.             vertex2frag vert(vertexInput v)
    234.             {
    235.                 vertex2frag o;
    236.  
    237.                 o.tangentWorld = -normalize(
    238.                     mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );    
    239.                 o.normalWorld = -normalize(
    240.                     mul( float4( v.normal, 0.0 ), unity_WorldToObject ).xyz );
    241.                 o.binormalWorld = normalize(
    242.                     cross( o.normalWorld, o.tangentWorld )
    243.                     * v.tangent.w);
    244.                        
    245.                 o.posWorld = mul( unity_ObjectToWorld, v.vertex );
    246.                 o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    247.                 o.tex = v.texcoord;
    248.  
    249.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    250.                 return o;
    251.             }
    252.        
    253.             // Fragment Function
    254.             float4 frag(vertex2frag i) : SV_Target
    255.             {
    256.                 float3 viewDirection = normalize( _WorldSpaceCameraPos.xyz - i.posWorld.xyz );
    257.  
    258. //                float atten = lerp( // lerp based on type of light, directional or point/spot
    259. //                    1.0,
    260. //                    1 / length(_WorldSpaceLightPos0.xyz - i.posWorld.xyz),
    261. //                    ceil(_WorldSpaceLightPos0.w)
    262. //                );
    263.                 float atten = LIGHT_ATTENUATION(i);
    264.                 float3 lightDirection = lerp( // lerp based on type of light, directional or point/spot
    265.                     normalize( _WorldSpaceLightPos0.xyz ),
    266.                     normalize( _WorldSpaceLightPos0.xyz - i.posWorld.xyz ),
    267.                     ceil(_WorldSpaceLightPos0.w)
    268.                 );
    269.                
    270.                 // Texture Maps
    271.                 float4 tex = tex2D( _BackMainTex, i.tex.xy * _BackMainTex_ST.xy + _BackMainTex_ST.zw );
    272.                 if(tex.a < _BackCutOff)
    273.                     discard;
    274.                 float4 texS = tex2D( _BackSpecTex, i.tex.xy * _BackSpecTex_ST.xy + _BackSpecTex_ST.zw );
    275.                 float4 texN = tex2D( _BackBumpMap, i.tex.xy * _BackBumpMap_ST.xy + _BackBumpMap_ST.zw );
    276.                 float4 texAo = tex2D( _BackAo, i.tex.xy * _BackAo_ST.xy + _BackAo_ST.zw );
    277.  
    278.                 // unpackNormal Function
    279.                 float3 localCoords = float3(2.0 * texN.a - 1.0,
    280.                     2.0 * texN.g - 1.0, 0.0);
    281.                 localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
    282.                
    283.                 // Normal Transpose Matrix
    284.                 float3x3 local2WorldTranspose = float3x3(
    285.                     i.tangentWorld,
    286.                     i.binormalWorld,
    287.                     i.normalWorld
    288.                 );
    289.                
    290.                 // Calculate Normal Direction
    291.                 float3 normalDirection = normalize( mul( localCoords, local2WorldTranspose ) );
    292.                
    293.                 // Lighting
    294.                 float3 ambientLighting =
    295.                     UNITY_LIGHTMODEL_AMBIENT.rgb * _BackColor.rgb * tex.rgb;
    296.                 float3 diffuseReflection =
    297.                     atten * _LightColor0.rgb * _BackColor.rgb * tex.rgb
    298.                     * max(0, dot( normalDirection, lightDirection) );
    299.                 float3 specularReflection = lerp( // lerp based on what side is the light
    300.                     float3(0, 0, 0),
    301.                     atten * _LightColor0.rgb *
    302.                     (_BackSpecColor.rgb * texS.rgb * _BackSpecIntensity) *
    303.                     pow(max(0.0, dot(
    304.                         reflect(-lightDirection, normalDirection),
    305.                         viewDirection)), _BackShininess * 100),
    306.                     floor(dot(normalDirection, lightDirection) + 1));
    307.  
    308.                 float4 finalLight = float4( (ambientLighting + diffuseReflection + specularReflection) * texAo.rgb, 1.0);
    309.                 return finalLight;
    310.             }
    311.        
    312.             ENDCG
    313.         }
    314.  
    315.         //_____________________________________ front pass for additional light sources
    316.         Pass
    317.         {  
    318.             Tags { "LightMode" = "ForwardAdd" }
    319.             Blend One One // additive blending
    320.             Cull Back // render only front faces
    321.          
    322.             CGPROGRAM
    323.            
    324.             #pragma vertex vert
    325.             #pragma fragment frag
    326. //            #pragma multi_compile_fwdadd                        // This line tells Unity to compile this pass for forward add, giving attenuation information for the light.
    327.             #pragma multi_compile_fwdadd_fullshadows                      // This line tells Unity to compile this pass for forward add and give shadow information as well as attenuation. Swap this line for the one above if you want forward add with shadows.
    328.             #pragma fragmentoption ARB_fog_exp2
    329.             #pragma fragmentoption ARB_precision_hint_fastest
    330.             #pragma target 3.0
    331.                        
    332.             #include "UnityCG.cginc"
    333.             #include "AutoLight.cginc"
    334.            
    335.             // Unity-defined variables
    336.             uniform float4 _LightColor0; // color of light source (from "Lighting.cginc")
    337.            
    338.             // User-specified properties
    339.             uniform float4 _Color;
    340.             uniform sampler2D _MainTex;
    341.             uniform float4 _MainTex_ST;
    342.             uniform float4 _SpecColor;
    343.             uniform sampler2D _SpecTex;
    344.             uniform float4 _SpecTex_ST;
    345.             uniform float _SpecIntensity;
    346.             uniform float _Shininess;
    347.             uniform sampler2D _BumpMap;
    348.             uniform float4 _BumpMap_ST;
    349.             uniform sampler _Ao;
    350.             uniform float4 _Ao_ST;
    351.             uniform float _CutOff;
    352.            
    353.             struct vertexInput
    354.             {
    355.                 float4 vertex : POSITION;
    356.                 float3 normal : NORMAL;
    357.                 float2 texcoord : TEXCOORD0;
    358.                 float4 tangent: TANGENT;
    359.             };
    360.             struct vertex2frag
    361.             {
    362.                 float4 pos : SV_POSITION;
    363.                 float2 tex : TEXCOORD0;
    364.                 float4 posWorld: TEXCOORD1;
    365.                 float3 normalWorld: TEXCOORD2;
    366.                 float3 tangentWorld: TEXCOORD3;
    367.                 float3 binormalWorld: TEXCOORD4;
    368.                 LIGHTING_COORDS(5, 6)
    369.             };
    370.  
    371.             // Vertex Function
    372.             vertex2frag vert(vertexInput v)
    373.             {
    374.                 vertex2frag o;
    375.  
    376.                 o.tangentWorld = normalize(
    377.                     mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );    
    378.                 o.normalWorld = normalize(
    379.                     mul( float4( v.normal, 0.0 ), unity_WorldToObject ).xyz );
    380.                 o.binormalWorld = normalize(
    381.                     cross( o.normalWorld, o.tangentWorld )
    382.                     * v.tangent.w);
    383.                        
    384.                 o.posWorld = mul( unity_ObjectToWorld, v.vertex );
    385.                 o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    386.                 o.tex = v.texcoord;
    387.  
    388.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    389.                 return o;
    390.             }
    391.        
    392.             // Fragment Function
    393.             float4 frag(vertex2frag i) : SV_Target
    394.             {
    395.                 float3 viewDirection = normalize( _WorldSpaceCameraPos.xyz - i.posWorld.xyz );
    396.  
    397. //                float atten = lerp( // lerp based on type of light, directional or point/spot
    398. //                    1.0,
    399. //                    1 / length(_WorldSpaceLightPos0.xyz - i.posWorld.xyz),
    400. //                    ceil(_WorldSpaceLightPos0.w)
    401. //                );
    402.                 float atten = LIGHT_ATTENUATION(i); // Macro to get you the combined shadow  attenuation value.
    403.                 float3 lightDirection = lerp( // lerp based on type of light, directional or point/spot
    404.                     normalize( _WorldSpaceLightPos0.xyz ),
    405.                     normalize( _WorldSpaceLightPos0.xyz - i.posWorld.xyz ),
    406.                     ceil(_WorldSpaceLightPos0.w)
    407.                 );
    408.                
    409.                 // Texture Maps
    410.                 float4 tex = tex2D( _MainTex, i.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw );
    411.                 if(tex.a < _CutOff)
    412.                     discard;
    413.                 float4 texS = tex2D( _SpecTex, i.tex.xy * _SpecTex_ST.xy + _SpecTex_ST.zw );
    414.                 float4 texN = tex2D( _BumpMap, i.tex.xy * _BumpMap_ST.xy + _BumpMap_ST.zw );
    415.                 float4 texAo = tex2D( _Ao, i.tex.xy * _Ao_ST.xy + _Ao_ST.zw );
    416.                
    417.                 // unpackNormal Function
    418.                 float3 localCoords = float3(2.0 * texN.a - 1.0,
    419.                     2.0 * texN.g - 1.0, 0.0);
    420.                 localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
    421.                
    422.                 // Normal Transpose Matrix
    423.                 float3x3 local2WorldTranspose = float3x3(
    424.                     i.tangentWorld,
    425.                     i.binormalWorld,
    426.                     i.normalWorld
    427.                 );
    428.                
    429.                 // Calculate Normal Direction
    430.                 float3 normalDirection = normalize( mul( localCoords, local2WorldTranspose ) );
    431.                
    432.                 // Lighting
    433.                 float3 diffuseReflection =
    434.                     atten * _LightColor0.rgb * _Color.rgb * tex.rgb
    435.                     * max(0, dot( normalDirection, lightDirection) );
    436.                 float3 specularReflection = lerp( // lerp based on what side is the light
    437.                     float3(0, 0, 0),
    438.                     atten * _LightColor0.rgb *
    439.                     (_SpecColor.rgb * texS.rgb * _SpecIntensity) *
    440.                     pow(max(0.0, dot(
    441.                         reflect(-lightDirection, normalDirection),
    442.                         viewDirection)), _Shininess * 100),
    443.                     floor(dot(normalDirection, lightDirection) + 1));
    444.  
    445.                 return float4( (diffuseReflection + specularReflection) * texAo.rgb, 1.0);
    446.             }
    447.        
    448.             ENDCG
    449.         }
    450.  
    451.         //_____________________________________ back pass for additional light sources
    452.         Pass
    453.         {  
    454.             Tags { "LightMode" = "ForwardAdd" }
    455.             Blend One One // additive blending
    456.             Cull Front // render only back faces
    457.          
    458.             CGPROGRAM
    459.            
    460.             #pragma vertex vert
    461.             #pragma fragment frag
    462. //            #pragma multi_compile_bckadd                        // This line tells Unity to compile this pass for forward add, giving attenuation information for the light.
    463.             #pragma multi_compile_bckadd_fullshadows                      // This line tells Unity to compile this pass for forward add and give shadow information as well as attenuation. Swap this line for the one above if you want forward add with shadows.
    464.             #pragma fragmentoption ARB_fog_exp2
    465.             #pragma fragmentoption ARB_precision_hint_fastest
    466.             #pragma target 3.0
    467.            
    468.             #include "UnityCG.cginc"
    469.             #include "AutoLight.cginc"
    470.            
    471.             // Unity-defined variables
    472.             uniform float4 _LightColor0; // color of light source (from "Lighting.cginc")
    473.            
    474.             // User-specified properties
    475.             uniform float4 _BackColor;
    476.             uniform sampler2D _BackMainTex;
    477.             uniform float4 _BackMainTex_ST;
    478.             uniform float4 _BackSpecColor;
    479.             uniform sampler2D _BackSpecTex;
    480.             uniform float4 _BackSpecTex_ST;
    481.             uniform float _BackSpecIntensity;
    482.             uniform float _BackShininess;
    483.             uniform sampler2D _BackBumpMap;
    484.             uniform float4 _BackBumpMap_ST;
    485.             uniform sampler _BackAo;
    486.             uniform float4 _BackAo_ST;
    487.             uniform float _BackCutOff;
    488.            
    489.             struct vertexInput
    490.             {
    491.                 float4 vertex : POSITION;
    492.                 float3 normal : NORMAL;
    493.                 float2 texcoord : TEXCOORD0;
    494.                 float4 tangent: TANGENT;
    495.             };
    496.             struct vertex2frag
    497.             {
    498.                 float4 pos : SV_POSITION;
    499.                 float2 tex : TEXCOORD0;
    500.                 float4 posWorld: TEXCOORD1;
    501.                 float3 normalWorld: TEXCOORD2;
    502.                 float3 tangentWorld: TEXCOORD3;
    503.                 float3 binormalWorld: TEXCOORD4;
    504.                 LIGHTING_COORDS(5,6)
    505.             };
    506.  
    507.             // Vertex Function
    508.             vertex2frag vert(vertexInput v)
    509.             {
    510.                 vertex2frag o;
    511.  
    512.                 o.tangentWorld = normalize(
    513.                     mul( unity_ObjectToWorld, float4( v.tangent.xyz, 0.0 ) ).xyz );    
    514.                 o.normalWorld = normalize(
    515.                     mul( float4( v.normal, 0.0 ), unity_WorldToObject ).xyz );
    516.                 o.binormalWorld = normalize(
    517.                     cross( o.normalWorld, o.tangentWorld )
    518.                     * v.tangent.w);
    519.                        
    520.                 o.posWorld = mul( unity_ObjectToWorld, v.vertex );
    521.                 o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
    522.                 o.tex = v.texcoord;
    523.  
    524.                 TRANSFER_VERTEX_TO_FRAGMENT(o);
    525.                 return o;
    526.             }
    527.        
    528.             // Fragment Function
    529.             float4 frag(vertex2frag i) : SV_Target
    530.             {
    531.                 float3 viewDirection = normalize( _WorldSpaceCameraPos.xyz - i.posWorld.xyz );
    532.  
    533. //                float atten = lerp( // lerp based on type of light, directional or point/spot
    534. //                    1.0,
    535. //                    1 / length(_WorldSpaceLightPos0.xyz - i.posWorld.xyz),
    536. //                    ceil(_WorldSpaceLightPos0.w)
    537. //                );
    538.                 float atten = LIGHT_ATTENUATION(i);
    539.                 float3 lightDirection = lerp( // lerp based on type of light, directional or point/spot
    540.                     normalize( _WorldSpaceLightPos0.xyz ),
    541.                     normalize( _WorldSpaceLightPos0.xyz - i.posWorld.xyz ),
    542.                     ceil(_WorldSpaceLightPos0.w)
    543.                 );
    544.                
    545.                 // Texture Maps
    546.                 float4 tex = tex2D( _BackMainTex, i.tex.xy * _BackMainTex_ST.xy + _BackMainTex_ST.zw );
    547.                 if(tex.a < _BackCutOff)
    548.                     discard;
    549.                 float4 texS = tex2D( _BackSpecTex, i.tex.xy * _BackSpecTex_ST.xy + _BackSpecTex_ST.zw );
    550.                 float4 texN = tex2D( _BackBumpMap, i.tex.xy * _BackBumpMap_ST.xy + _BackBumpMap_ST.zw );
    551.                 float4 texAo = tex2D( _BackAo, i.tex.xy * _BackAo_ST.xy + _BackAo_ST.zw );
    552.  
    553.                 // unpackNormal Function
    554.                 float3 localCoords = float3(2.0 * texN.a - 1.0,
    555.                     2.0 * texN.g - 1.0, 0.0);
    556.                 localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
    557.                
    558.                 // Normal Transpose Matrix
    559.                 float3x3 local2WorldTranspose = float3x3(
    560.                     i.tangentWorld,
    561.                     i.binormalWorld,
    562.                     i.normalWorld
    563.                 );
    564.                
    565.                 // Calculate Normal Direction
    566.                 float3 normalDirection = -normalize( mul( localCoords, local2WorldTranspose ) );
    567.                
    568.                 // Lighting
    569.                 float3 diffuseReflection =
    570.                     atten * _LightColor0.rgb * _BackColor.rgb * tex.rgb
    571.                     * max(0, dot( normalDirection, lightDirection) );
    572.                 float3 specularReflection = lerp( // lerp based on what side is the light
    573.                     float3(0, 0, 0),
    574.                     atten * _LightColor0.rgb *
    575.                     (_BackSpecColor.rgb * texS.rgb * _BackSpecIntensity) *
    576.                     pow(max(0.0, dot(
    577.                         reflect(-lightDirection, normalDirection),
    578.                         viewDirection)), _BackShininess * 100),
    579.                     floor(dot(normalDirection, lightDirection) + 1));
    580.  
    581.                 float4 finalLight = float4( ( diffuseReflection + specularReflection) * texAo.rgb, 1.0);
    582.                 return finalLight;
    583.             }
    584.          
    585.             ENDCG
    586.         }
    587.    }
    588.  
    589.    Fallback "Specular"
    590. }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    You wrote a custom double sided shader, but not a custom shadow caster pass. The main directional light shadows use the shadow caster pass for shadow receiving as well.

    http://aras-p.info/blog/2009/11/04/deferred-cascaded-shadow-maps/

    There's a basic shadow caster example here:
    https://docs.unity3d.com/Manual/SL-VertexFragmentShaderExamples.html

    If you add Cull Off to that pass it should work more like you expect it to, though you'll want to modify it to include the same alpha testing you do in your main passes.


    Additionally I would suggest looking into using the VFACE semantic and doing away with separate front and back faces.