Orihaus

Main Shader - August 2013 v2.5 - UE4 Light Model Fixed

Aug 2nd, 2013
1,165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.88 KB | None | 0 0
  1. Shader "Base_Texture"
  2. {
  3.     Properties  
  4.     {
  5.         _DiffuseAmount ( "Diffuse Amount", Range( 0.0, 1.0 ) ) = 0.25
  6.         _TexAmount ( "Texture Amount", Range( 0.0, 1.0 ) ) = 0.25
  7.         _SpecAmount ( "Specular Amount", Range( 0.0, 16.0 ) ) = 1.0
  8.         _SpecTexAmount ( "Spec Texture Amount", Range( 0.0, 1.0 ) ) = 0.25
  9.        
  10.         _Diffusemap ( "Diffusemap", 2D ) = "diffuse" {}
  11.         _Normalmap ( "Normalmap", 2D ) = "normal" {}
  12.         _Specmap ( "Specmap", 2D ) = "spec" {}
  13.        
  14.         _Gloss ( "Gloss", Range( 0.001, 1.0 ) ) = 1.0
  15.         _SRNI ( "Specular Reflectance at Normal Incidence", Range( 0.0, 1.0 ) ) = 0.075
  16.     }
  17.        
  18.     SubShader
  19.     {
  20.         Tags
  21.         {
  22.           "Queue"="Geometry+0"
  23.           "IgnoreProjector"="False"
  24.           "RenderType"="Opaque"
  25.         }
  26.  
  27.         Cull Back
  28.         ZWrite On
  29.         ZTest LEqual
  30.  
  31.         CGPROGRAM
  32.         #pragma debug
  33.         #pragma target 3.0
  34.         #pragma surface surf SimpleSpecular novertexlights noambient nolightmap nodirlightmap
  35.        
  36.         float _Gloss;
  37.         fixed _SpecAmount;
  38.         float _SRNI;
  39.        
  40.         float CalculateGGX( float alpha, float cosThetaM )
  41.         {
  42.             float roughness = alpha * alpha;
  43.             roughness *= roughness;
  44.            
  45.             float CosSquared = cosThetaM * cosThetaM;
  46.             float TanSquared = ( 1.0 - CosSquared ) + 1.0;
  47.             float GGX = ( CosSquared * ( roughness - 1.0 ) ) + 1.0;
  48.             GGX = 0.31831 * GGX * GGX;
  49.             return roughness / GGX;
  50.         }
  51.        
  52.         float CalculateGeometric( float n_dot_v, float roughness )
  53.         {
  54.             return n_dot_v / ( n_dot_v * ( 1.0 - roughness ) + roughness );
  55.         }
  56.        
  57.         float CalculateGeometricAtten( float n_dot_l, float n_dot_v, float roughness )
  58.         {
  59.             float roughnessRemap = roughness + 1.0;
  60.             roughnessRemap *= roughnessRemap;
  61.             roughnessRemap *= 0.125;
  62.            
  63.             float atten = CalculateGeometric( n_dot_v, roughnessRemap ) * CalculateGeometric( n_dot_l, roughnessRemap );
  64.             return atten;
  65.         }
  66.  
  67.         float CalculateSpecular( fixed3 lDir, fixed3 vDir, fixed3 norm, float lightSize, float lightDistance, float gloss, float n_dot_l )
  68.         {    
  69.             float3 halfVector = normalize( lDir + vDir );
  70.        
  71.             float n_dot_v = saturate( dot( norm, vDir ) );
  72.             float h_dot_n = saturate( dot( halfVector, norm ) );
  73.             float h_dot_v = saturate( dot( halfVector, vDir ) );
  74.            
  75.             float fresnel = pow( 1.0 - h_dot_v, 5.0 );
  76.             fresnel = _SRNI + ( 1.0 - _SRNI ) * fresnel;
  77.  
  78.             float geoAtten = CalculateGeometricAtten( n_dot_l, h_dot_v, gloss );
  79.             float distribution = CalculateGGX( saturate( gloss + ( lightSize / ( 3.0 * lightDistance ) ) * _WorldSpaceLightPos0.w ), h_dot_n );
  80.            
  81.             float BRDF = distribution * fresnel * geoAtten * saturate( h_dot_v / ( h_dot_n * n_dot_v ) );
  82.             return BRDF;
  83.         }
  84.        
  85.         struct SurfaceOutputMod
  86.         {
  87.             half3 Albedo;
  88.             half3 Normal;
  89.             half3 Emission;
  90.             half Specular;
  91.             half Gloss;
  92.             half Alpha;
  93.             float3 position;
  94.         };
  95.        
  96.         fixed4 LightingSimpleSpecular( SurfaceOutputMod s, fixed3 lightDir, fixed3 viewDir, fixed atten )
  97.         {
  98.             float lightDistance = length( _WorldSpaceLightPos0.xyz - s.position );
  99.             fixed lightSize = _LightColor0.w * 4.0;
  100.            
  101.             float n_dot_l = saturate( dot( s.Normal, lightDir ) );
  102.             fixed spec = CalculateSpecular( lightDir, viewDir, s.Normal, lightSize, lightDistance, s.Gloss, n_dot_l ) * 0.005 * _SpecAmount;
  103.             fixed3 diff = n_dot_l * s.Albedo * 0.31831;
  104.            
  105.             diff = lerp( diff, 0.0, spec );
  106.            
  107.             fixed4 c;
  108.             c.rgb = diff * _LightColor0.rgb;
  109.             c.rgb += _LightColor0.rgb * spec;
  110.             c.rgb *= atten * 2.0;
  111.             c.a = s.Alpha;
  112.            
  113.             return c;
  114.         }
  115.        
  116.         fixed4 LightingSimpleSpecular_DirLightmap( SurfaceOutputMod s, fixed4 color, fixed4 scale, fixed3 viewDir, bool surfFuncWritesNormal, out fixed3 specColor )
  117.         {
  118.             UNITY_DIRBASIS
  119.             half3 scalePerBasisVector;
  120.            
  121.             half3 lm = DirLightmapDiffuse( unity_DirBasis, color, scale, s.Normal, surfFuncWritesNormal, scalePerBasisVector );
  122.             half3 lightDir = normalize( scalePerBasisVector.x * unity_DirBasis[0] + scalePerBasisVector.y * unity_DirBasis[1] + scalePerBasisVector.z * unity_DirBasis[2 ]);
  123.            
  124.             specColor = lm * CalculateSpecular( lightDir, viewDir, s.Normal, 0.0, 0.0, s.Gloss, saturate( dot( s.Normal, lightDir ) ) ) * 0.005 * _SpecAmount;
  125.            
  126.             return half4( lm * 0.5, 1.0 );
  127.         }
  128.        
  129.         struct Input  
  130.         {
  131.             float2 uv_Diffusemap;
  132.             float2 uv_Normalmap;
  133.             float2 uv_Specmap;
  134.             float3 worldPos;
  135.         };
  136.        
  137.         sampler2D _Diffusemap;
  138.         sampler2D _Normalmap;
  139.         sampler2D _Specmap;
  140.  
  141.         fixed _SpecTexAmount;
  142.         fixed _TexAmount;
  143.         fixed _DiffuseAmount;
  144.  
  145.         void surf( Input IN, inout SurfaceOutputMod o )
  146.         {
  147.             o.Normal = UnpackNormal( tex2D( _Normalmap, IN.uv_Normalmap ) );
  148.            
  149.             float spec = tex2D( _Specmap, IN.uv_Specmap ).r;
  150.             o.Gloss = lerp( spec * 2.0, 0.5, _SpecTexAmount ) * _Gloss;
  151.             o.Albedo = _DiffuseAmount * lerp( tex2D( _Diffusemap, IN.uv_Diffusemap ), 1.0, _TexAmount );
  152.             o.position = IN.worldPos;
  153.         }
  154.    
  155.         ENDCG
  156.     }
  157.        
  158.     Fallback "Diffuse"
  159. }
Advertisement
Add Comment
Please, Sign In to add comment