Guest User

Untitled

a guest
Apr 10th, 2017
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Shader "ShaderChallenge/CustomPBR"
  2. {
  3.     Properties
  4.     {
  5.         _Albedo("Albedo", 2D) = "white" {}
  6.         _Roughness("Roughness", Range(0, 1)) = 1.0
  7.         _Metallic("Metallic", Range(0, 1)) = 0.0
  8.     }
  9.     SubShader
  10.     {
  11.         Pass
  12.         {
  13.             Tags { "LightMode" = "ForwardBase" }
  14.  
  15.             CGPROGRAM
  16.             #pragma vertex vert
  17.             #pragma fragment frag
  18.             #include "UnityStandardBRDF.cginc"
  19.             #include "UnityStandardUtils.cginc"
  20.  
  21.             #define pi 3.14159265359
  22.  
  23.             sampler2D _Albedo;
  24.             float _Roughness;
  25.             float _Metallic;
  26.  
  27.             struct v2f
  28.             {
  29.                 float4 pos : SV_POSITION;
  30.                 float3 worldPos : TEXCOORD0;
  31.                 float3 normal : TEXCOORD1;
  32.                 float2 uv : TEXCOORD2;
  33.             };
  34.  
  35.             v2f vert(appdata_base v)
  36.             {
  37.                 v2f o;
  38.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
  39.                 // Convert vertex position to world space
  40.                 o.worldPos = mul(unity_ObjectToWorld, v.vertex);
  41.                 // Normal vector
  42.                 o.normal = UnityObjectToWorldNormal(v.normal);
  43.                 o.uv = v.texcoord;
  44.                 return o;
  45.             }
  46.  
  47.             // Oren-Nayar
  48.             float OrenNayar(float3 n, float3 v, float3 l)
  49.             {
  50.                 float nl = dot(n, l);
  51.                 float nv = dot(n, v);
  52.  
  53.                 float anglenl = acos(nl);
  54.                 float anglenv = acos(nv);
  55.  
  56.                 float alpha = max(anglenv, anglenl);
  57.                 float beta = min(anglenv, anglenl);
  58.                 float gamma = dot(v - n * nv, l - n * nl);
  59.  
  60.                 float a2 = pow(_Roughness, 2.0);
  61.  
  62.                 float A = 1.0 - 0.5 * (a2 / (a2 + 0.57));
  63.    
  64.                 float B = 0.45 * (a2 / (a2 + 0.09));
  65.    
  66.                 float C = sin(alpha) * tan(beta);
  67.    
  68.                 float result = max(0.0, nl) * (A + B * max(0.0, gamma) * C);
  69.    
  70.                 return result;
  71.             }
  72.  
  73.             float DistributionGGX(float3 n, float3 h)
  74.             {
  75.                 float a2 = pow(_Roughness, 2.0);
  76.                 float nh = dot(n, h);
  77.                 float nh2 = pow(nh, 2.0);
  78.  
  79.                 float num = a2;
  80.                 float den = (nh2 * (a2 - 1.0) + 1.0);
  81.                 den = pi * pow(den, 2.0);
  82.  
  83.                 return num / den;
  84.             }
  85.            
  86.             float GeometrySchlickGGX(float dot, float k)
  87.             {
  88.                 float num   = dot;
  89.                 float den = dot * (1.0 - k) + k;
  90.    
  91.                 return num / den;
  92.             }
  93.  
  94.             float GeometrySmith(float3 n, float3 v, float3 l)
  95.             {
  96.                 float k = pow(_Roughness + 1.0, 2.0) / 8.0;
  97.  
  98.                 float nv = DotClamped(n, v);
  99.                 float nl = DotClamped(n, l);
  100.                 float ggx1 = GeometrySchlickGGX(nv, k);
  101.                 float ggx2 = GeometrySchlickGGX(nl, k);
  102.  
  103.                 return ggx1 * ggx2;
  104.             }
  105.  
  106.             float FresnelSchlick(float3 n, float3 v, float3 albedo)
  107.             {
  108.                 float cosTheta = dot(n, v);
  109.                 float3 F0 = 0.04;
  110.                 F0 = lerp(F0, albedo, _Metallic);
  111.  
  112.                 return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
  113.             }
  114.  
  115.             float Microfacet(float3 n, float3 h, float3 v, float3 l, float3 albedo)
  116.             {
  117.                 float d = DistributionGGX(h, n);
  118.                 float g = GeometrySmith(n, v, l);
  119.                 float f = FresnelSchlick(n, v, albedo);
  120.    
  121.                 return (d * g * f) / 4.0 * DotClamped(n, l) * DotClamped(n, v) + 0.001;
  122.             }
  123.  
  124.             float4 frag(v2f i) : SV_TARGET
  125.             {
  126.                 float3 lightCol = _LightColor0.rgb;
  127.  
  128.                 // Normalize the normal
  129.                 float3 n = normalize(i.normal);
  130.                 // Light vector from mesh's surface
  131.                 float3 l = normalize(_WorldSpaceLightPos0.xyz);
  132.                 // Viewport(camera) vector from mesh's surface
  133.                 float3 v = normalize(_WorldSpaceCameraPos - i.worldPos.xyz);
  134.                 // Halfway vector
  135.                 float3 h = normalize(l + v);
  136.  
  137.                 float3 albedo = tex2D(_Albedo, i.uv).rgb;
  138.                 float3 ambient = unity_AmbientSky;
  139.  
  140.                 float3 specular = Microfacet(n, h, v, l, albedo);
  141.  
  142.                 float3 diffuse = ambient + OrenNayar(n, v, l);
  143.                 diffuse *= 1.0 - _Metallic;
  144.  
  145.                 float3 color = albedo * (diffuse * lightCol) + (specular * lightCol);
  146.  
  147.                 return float4(color, 1.0);
  148.             }
  149.             ENDCG
  150.         }
  151.     }
  152. }
Add Comment
Please, Sign In to add comment