Advertisement
Gary_Keen27

Cook-Torrance Shading

Oct 25th, 2016
1,479
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /////////////////////////////////////////////////////
  2. ////////////////////VERTEX SHADER////////////////////
  3. /////////////////////////////////////////////////////
  4. #version 330
  5.  
  6. layout(location = 0) in vec3 inPosition;
  7. layout(location = 1) in vec3 inNormal;
  8. layout(location = 2) in vec2 inTexCoord;
  9. layout(location = 3) in vec3 inTangent;
  10. layout(location = 4) in vec3 inBitangent;
  11.  
  12. out vec2 texCoord;
  13. out vec3 camDir;
  14. out vec3 lightDir;
  15. out float attenuation;
  16.  
  17. uniform mat4 viewMatrix;
  18. uniform mat4 modelMatrix;
  19. uniform mat4 projectionMatrix;
  20. uniform mat3 normalMatrix;
  21. uniform vec3 camPosIn;
  22. uniform vec3 lightPosIn;
  23.  
  24. void main()
  25. {
  26.     vec3 N = normalize(normalMatrix * inNormal);
  27.     vec3 T = normalize(normalMatrix * inTangent);
  28.          T = normalize(T - (dot(N, T) * N));
  29.     vec3 B = normalize(normalMatrix * inBitangent);
  30.  
  31.     if (dot(cross(N, T), B) < 0.0)
  32.         T = T * -1.0;
  33.  
  34.     mat3 TBNMatrix = transpose(mat3(T, B, N));
  35.  
  36.     vec3 position = vec3((viewMatrix * modelMatrix) * vec4(inPosition, 1.0)); //Vector is a position so W = 1.0. If it were a direction w = 0.0.
  37.     camDir = TBNMatrix * (normalize(camPosIn - position));
  38.     lightDir = TBNMatrix * (normalize(lightPosIn - position));
  39.     texCoord = inTexCoord;
  40.  
  41.     float radius = 50.0;
  42.     float dist = length(vec3((viewMatrix * modelMatrix) * vec4(lightPosIn, 1.0)) - position);
  43.     attenuation = 1.0 / (1.0 + ((2.0 / radius) * dist) + ((1.0 / (radius * radius)) * (dist * dist)));
  44.  
  45.     gl_Position = (projectionMatrix * (viewMatrix * modelMatrix)) * vec4(inPosition, 1.0);
  46. }
  47.  
  48. ///////////////////////////////////////////////////////
  49. ////////////////////FRAGMENT SHADER////////////////////
  50. ///////////////////////////////////////////////////////
  51. #version 330
  52. precision mediump float;
  53.  
  54. in vec2 texCoord;
  55. in vec3 camDir;
  56. in vec3 lightDir;
  57. in float attenuation;
  58.  
  59. layout (location = 0) out vec4 FragColour;
  60.  
  61. uniform sampler2D textureMap;
  62. uniform sampler2D normalMap;
  63. uniform sampler2D AOMap;
  64. uniform sampler2D specMap;
  65. uniform sampler2D roughMap;
  66. uniform vec3 lightColour;
  67.  
  68. const float PI = 3.14159;
  69.  
  70. /////////////////////////////////////////////////
  71. //////////Normal Distribution Functions//////////
  72. /////////////////////////////////////////////////
  73. float D_Beckmann(float NH2, float tan2Alpha, float roughness2) //Beckmann = exp(-tan^2(alpha) / m^2) / PI * m^2 * cos^4(alpha)
  74. {
  75.     float denom = PI * roughness2 * (pow(NH2, 2.0));
  76.     return exp(tan2Alpha / roughness2) / denom;
  77. }
  78.  
  79. float D_TrowbridgeReitz(float NH2, float roughness2) //Trowbridge-Reitz = m^2 / (1 - m^2) * cos^2(alpha) - 1
  80. {
  81.     float denom = NH2 * roughness2 + (1.0 - NH2);
  82.     return roughness2 / (PI * pow(denom, 2.0));
  83. }
  84.  
  85. ///////////////////////////////////////////////////
  86. //////////Geometric Attenuation Functions//////////
  87. ///////////////////////////////////////////////////
  88. float G_CookTorrance(float NH2, float NdotV, float NdotL, float VdotH) //Cook-Torrance = min(1, ((N.H)^2 * (N.V)) / (V.H), ((N.H)^2 * (N.L)) / (V.H))
  89. {
  90.     float g1 = (NH2 * NdotV) / VdotH;
  91.     float g2 = (NH2 * NdotL) / VdotH;
  92.     return min(1.0, min(g1, g2));
  93. }
  94.  
  95. float G_GGXSmith(float roughness2, float NdotV, float NdotL)
  96. {
  97.     float g1 = (NdotL * 2.0) / (NdotL + sqrt(roughness2 + (1.0 - roughness2) * pow(NdotL, 2.0)));
  98.     float g2 = (NdotV * 2.0) / (NdotV + sqrt(roughness2 + (1.0 - roughness2) * pow(NdotV, 2.0)));
  99.     return g1 * g2;
  100. }
  101.  
  102. float G_BeckmannSmith(float NdotV, float NdotL, float roughness)
  103. {
  104.     float g1 = NdotV / roughness * sqrt(1.0 - (pow(NdotV, 2.0)));
  105.     float g2 = NdotL / roughness * sqrt(1.0 - (pow(NdotL, 2.0)));
  106.  
  107.     if (g1 >= 1.6)
  108.         g1 = ((3.535 * g1) + pow((2.181 * g1), 2.0)) / 1.0 + (2.276 * g1) + pow((2.577 * g1), 2.0);
  109.     else
  110.         g1 = 1.0;
  111.  
  112.     if (g2 >= 1.6)
  113.         g2 = ((3.535 * g2) + pow((2.181 * g2), 2.0)) / 1.0 + (2.276 * g2) + pow((2.577 * g2), 2.0);
  114.     else
  115.         g2 = 1.0;
  116.  
  117.     return g1 * g2;
  118. }
  119.  
  120. float G_Neumann(float NdotL, float NdotV)
  121. {
  122.     return (NdotL * NdotV) / max(NdotL, NdotV);
  123. }
  124.  
  125. float G_Kelemen(float NdotL, float NdotV, float VdotH)
  126. {
  127.     return (NdotL * NdotV) / pow(VdotH, 2.0);
  128. }
  129.  
  130. /////////////////////////////////////
  131. //////////Fresnel Functions//////////
  132. /////////////////////////////////////
  133. float F_Shlick(float NdotL, float Kr) //Shlick Approximation = Kr + (1 - Kr) * (1 - (N.V))^5
  134. {
  135.     return Kr + (1.0 - Kr) * pow((1.0 - NdotL), 5.0);
  136. }
  137.  
  138. float F_CookTorrance(float VdotH, float Kr)
  139. {
  140.     float n = (1.0 + sqrt(Kr)) / (1.0 - sqrt(Kr));
  141.     float g = sqrt(pow(n, 2.0) + pow(VdotH, 2.0) - 1.0);
  142.     return 0.5 * pow((g - VdotH) / (g + VdotH), 2.0) * (1.0 + pow(((g + VdotH) * VdotH - 1.0) / ((g - VdotH) * VdotH + 1.0), 2.0));
  143. }
  144.  
  145.  
  146. /////////////////////////////////
  147. //////////Main Function//////////
  148. /////////////////////////////////
  149. void main() //Cook-Torrance = (F/PI) * (D*G)/((N.L)*(N.V))
  150. {  
  151.     float mirror = 0.0;
  152.     float air = 1.0;
  153.     float bubble = 1.1;
  154.     float ice = 1.31;
  155.     float water = 1.33;
  156.     float glass = 1.5;
  157.     float standard = 2.0;
  158.     float steel = 2.5;
  159.    
  160.     vec3 albedo = texture(textureMap, texCoord).rgb;
  161.     vec3 normals = normalize(texture(normalMap, texCoord).rgb * 2.0 - 1.0);
  162.     float roughness = texture(roughMap, texCoord).r;
  163.     float spec = texture(specMap, texCoord).r;
  164.     float AO = texture(AOMap, texCoord).r; 
  165.    
  166.     float NdotV = max(dot(normals, camDir), 0.0);
  167.    
  168.     vec3 diffuse = vec3(0.0);
  169.     vec3 CookTorrance = vec3(0.0);
  170.     vec3 ambientColour = vec3(0.0);
  171.     vec3 test = vec3(0.0);
  172.  
  173.     for (int i = 0; i < 1; i++)
  174.     {
  175.         vec3 halfAngle = normalize(camDir + lightDir);
  176.         float NdotL = max(dot(normals, lightDir), 0.0);
  177.         float NdotH = max(dot(normals, halfAngle), 0.0);
  178.         float VdotH = max(dot(camDir, halfAngle), 0.0);
  179.        
  180.         float NH2 = pow(NdotH, 2.0);
  181.         float tan2Alpha = (NH2 - 1.0) / NH2;
  182.         float roughness2 = pow(clamp(roughness, 0.01, 0.99), 2.0);
  183.         float Kr = pow((1.0 - standard) / (1.0 + standard), 2.0);
  184.        
  185.         float F = F_Shlick(NdotV, Kr);
  186.         float D = D_TrowbridgeReitz(NH2, roughness2);
  187.         float G = G_GGXSmith(roughness2, NdotV, NdotL);
  188.         vec3 specular = spec * (lightColour * ((F * G * D) / ((PI * NdotV))));
  189.         vec3 lambertian = (1.0 - roughness) * (lightColour * NdotL);
  190.  
  191.         test += lightColour * D;
  192.         diffuse += lambertian * attenuation;
  193.         CookTorrance += specular * attenuation;
  194.         ambientColour += lightColour * attenuation;
  195.     }
  196.     float mipMapLevel = roughness * 12.0;
  197.     vec3 ambience = (0.01 * ambientColour) * AO;
  198.  
  199.     vec3 final = albedo * (ambience + diffuse + CookTorrance);
  200.     final = pow(final, vec3(1.0 / 2.2));
  201.     FragColour = vec4(final, 1.0);
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement