Want more features on Pastebin? Sign Up, it's FREE!
Guest

BRDF

By: a guest on Feb 25th, 2013  |  syntax: C  |  size: 2.83 KB  |  views: 106  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. analytic
  2.  
  3. ::begin parameters
  4. color Diffuse 1 0 0
  5. color Specular 1 1 1
  6. float DiffuseScale 0 1 0.5
  7. float SpecularScale 0 1 .028
  8. float Roughness 0.00005 2 0.2
  9. float Roughness2 0.00005 2 0.2
  10. float Retroreflective 0 1 0
  11. bool FullFresnel 0 1 0
  12. bool isotropic 1
  13. ::end parameters
  14.  
  15. ::begin shader
  16.  
  17. //Thanks to Chris_F for starting ideas.
  18. // Cook-Torrance, GGX distribution (bastardised with ashikhman shirley), Smith geometry, qualitative Oren-Nayar diffuse.
  19.  
  20. float saturate(float x) { return clamp(x,0,1); }
  21.  
  22. vec3 Fresnel(float CosTheta, vec3 Ks)
  23. {
  24.         CosTheta = min(CosTheta, 0.99999999999999999);
  25.         vec3 n2 = (1.0 + sqrt(Ks)) / (1.0 - sqrt(Ks));
  26.         vec3 SinTheta = vec3(sqrt(1 - CosTheta * CosTheta));
  27.  
  28.         vec3 SinThetaT = SinTheta / n2;
  29.         vec3 CosThetaT = sqrt(1 - SinThetaT * SinThetaT);
  30.  
  31.         vec3 n2CosThetaT = n2 * CosThetaT;
  32.         vec3 n2CosTheta = n2 * CosTheta;
  33.  
  34.         vec3 RsSqrt = (CosTheta - n2CosThetaT) / (CosTheta + n2CosThetaT);
  35.         vec3 Rs = RsSqrt * RsSqrt;
  36.  
  37.         vec3 RpSqrt = (n2CosTheta - CosThetaT) / (n2CosTheta + CosThetaT);
  38.         vec3 Rp = RpSqrt * RpSqrt;
  39.  
  40.         return (Rs + Rp) / 2;
  41. }
  42.  
  43. vec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y )
  44. {
  45. //vec3 temp = L; L = V; V = temp;
  46.         float PI = 3.14159265358979323846;
  47.         vec3 Kd = Diffuse * DiffuseScale;
  48.         vec3 Ks = Specular * SpecularScale;
  49.  
  50.         vec3 H = normalize(L + V);
  51.         float NdotL = clamp(dot(N, L), 0, 1);
  52.         float NdotV = dot(N, V);
  53.         float NdotH = dot(N, H);
  54.         float LdotV = dot(L, V);
  55.         float VdotH = dot(V, H);
  56.         float LdotH = dot(L, H);
  57.         float HdotX = dot(H,X);
  58.         float HdotY = dot(H,Y);
  59.                
  60.         float m1 = 1/Roughness;
  61.         float m2 = 1/Roughness2;
  62.         float M = isotropic ? Roughness : (1-(NdotH*NdotH)) / ( m1*HdotX*HdotX + m2*HdotY*HdotY );
  63.         float M_2 = isotropic ? M * M : M* min(Roughness, Roughness2);
  64.        
  65.         NdotH = mix( mix( NdotH, max(NdotH,LdotV), saturate(Retroreflective*2) ), LdotV, saturate(Retroreflective*2-1) );
  66.        
  67.         float NdotL_2 = NdotL * NdotL;
  68.         float NdotV_2 = NdotV * NdotV;
  69.         float NdotH_2 = NdotH * NdotH;
  70.         float OneMinusNdotL_2 = 1.0 - NdotL_2;
  71.         float OneMinusNdotV_2 = 1.0 - NdotV_2;
  72.  
  73.         vec3 Fd = 1.0 - Ks;
  74.  
  75.         float gamma = clamp(dot(V - N * NdotV, L - N * NdotL), 0, 1);
  76.         float A = 1.0 - 0.5 * (M_2 / (M_2 + 0.33));
  77.         float B = 0.45 * (M_2 / (M_2 + 0.09));
  78.         float C = sqrt(OneMinusNdotL_2 * OneMinusNdotV_2) / max(NdotL, NdotV);
  79.  
  80.         vec3 Rd = Kd * Fd * (A + B * gamma * C) * 1/PI;
  81.        
  82.         float ggxDenom = NdotH_2 * (M_2 + (1-NdotH_2)/NdotH_2);
  83.         float D = M/ggxDenom;
  84.         D = D*D/PI;
  85.         D *= isotropic ? 1 : min(m1,m2)/max(m1,m2);
  86.        
  87.         vec3 Fs;
  88.         if( FullFresnel )
  89.                 Fs = Fresnel(NdotV, Ks);
  90.         else
  91.                 Fs = Ks + Fd * pow(1-LdotH, 5);
  92.  
  93.         float G1_1 = 1.0 + sqrt(1.0 + M_2 * (OneMinusNdotL_2 / NdotL_2));
  94.         float G1_2 = 1.0 + sqrt(1.0 + M_2 * (OneMinusNdotV_2 / NdotV_2));
  95.         float G = ((2/G1_1) * (2/G1_2))/(4 * NdotV * NdotL);
  96.        
  97.         vec3 Rs = Fs * D * G;
  98.        
  99.         return vec3(Rd + Rs);
  100. }
  101.  
  102. ::end shader
clone this paste RAW Paste Data