Advertisement
Guest User

Diffuse + Specular BRDF (GLSL)

a guest
Aug 19th, 2015
981
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.02 KB | None | 0 0
  1. #version 330 core
  2.  
  3. #define M_PI 3.14159265359
  4.  
  5. struct BaseLight
  6. {
  7.     vec3 Color;
  8.     float AmbientIntensity;
  9.     float DiffuseIntensity;
  10. };
  11.  
  12. struct DirectionalLight
  13. {
  14.     BaseLight Base;
  15.     vec3 Direction;
  16. };
  17.  
  18. uniform sampler2DArray GBuffer;
  19. uniform DirectionalLight gDirectionalLight;
  20. uniform vec3 gEyeWorldPos;
  21. uniform float gMatSpecularIntensity;
  22. uniform float gSpecularPower;
  23. uniform vec2 gScreenSize;
  24.  
  25. layout (location = 4) out vec4 FragColor;
  26.  
  27. vec2 CalcTexCoord()
  28. {
  29.     return gl_FragCoord.xy / gScreenSize;
  30. }
  31.  
  32. float F_Schlick (in float f0, in float f90, in float u)
  33. {
  34.     return f0 + ( f90 - f0 ) * pow(clamp(1.0 - u, 0.0, 1.0), 5.0);
  35. }
  36.  
  37.  float Fr_DisneyDiffuse ( float dotNV , float dotNL , float dotLH , float linearRoughness )
  38. {
  39.     float energyBias = mix(0 , 0.5 , linearRoughness);
  40.     float energyFactor = mix(1.0 , 1.0 / 1.51 , linearRoughness);
  41.     float fd90 = energyBias + 2.0 * dotLH * dotLH * linearRoughness;
  42.     const float f0 = 1.0;
  43.     float lightScatter = F_Schlick(f0 , fd90 , dotNL);
  44.     float viewScatter = F_Schlick(f0 , fd90 , dotNV);
  45.    
  46.     return lightScatter * viewScatter * energyFactor;
  47. }
  48.  
  49. float GGX_D(float dotNH, float alpha)
  50. {
  51.     float m_alpha = pow(alpha, 2.0);
  52.     return m_alpha / (M_PI * pow( pow(dotNH, 2.0) * (m_alpha - 1.0) + 1.0 , 2.0));
  53. }
  54.  
  55. float G1(float dotNV, float k)
  56. {
  57.     return dotNV / (dotNV * (1.0 - k) + k);
  58. }
  59.  
  60. float GGX_G(float dotNL, float dotNV, float roughness)
  61. {
  62.     float k = pow(roughness + 1.0, 2.0) / 8;
  63.     return G1(dotNL, k) * G1(dotNV, k);
  64. }
  65.  
  66. float GGX_F(float dotVH, float F0)
  67. {
  68.     float powerForTwo = (-5.55473 * dotVH - 6.98316) * dotVH;
  69.     return mix(pow(2.0, powerForTwo), 1.0, F0);
  70. }
  71.  
  72. float PBR(vec3 N, vec3 V, vec3 L, float roughness, float f0)
  73. {
  74.    
  75.     vec3 H = normalize (V + L);
  76.     float dotNV = abs(dot(N, V));
  77.     float dotNL = abs(dot(N, L));
  78.     float dotLH = clamp(dot(L, H), 0.0, 1.0);
  79.     float dotNH = clamp(dot(N, H), 0.0, 1.0);
  80.    
  81.     float f90 = clamp(50.0 * dot (f0 , 0.33), 0.0, 1.0);
  82.     float alpha = pow(roughness, 2.0);
  83.    
  84.     // Specular BRDF
  85.     float F = GGX_F(clamp(dot(V, H), 0.0, 1.0), f0);
  86.     float D = GGX_D(dotNH, alpha);;
  87.     float G = GGX_G(dotNL, dotNV, roughness);
  88.     float Fr = D * F * G / (4 * dotNL * dotNV);
  89.    
  90.     // Diffuse BRDF
  91.     float Fd = Fr_DisneyDiffuse(dotNV, dotNL, dotLH, roughness) / M_PI;
  92.  
  93.     return Fr + Fd;
  94.  
  95. }
  96.  
  97. void main()
  98. {
  99.     vec2 TexCoord = CalcTexCoord();
  100.     vec3 WorldPos = texture(GBuffer, vec3(TexCoord.xy, 0)).xyz;
  101.     vec3 Color = texture(GBuffer, vec3(TexCoord.xy, 1)).xyz;
  102.     vec3 Normal = normalize(texture(GBuffer, vec3(TexCoord.xy, 2)).xyz);
  103.     vec3 ViewDirection = normalize(gEyeWorldPos - WorldPos);
  104.    
  105.     // Set material parameters
  106.     vec3 surface = vec3(0.7, 0.7, 0.4);  
  107.         float reflectance = surface.r;
  108.         //float roughness = clamp(surface.g - EPSILON,0.0,1.0) + EPSILON;
  109.     float roughness = surface.g;
  110.         float metallic = surface.b;
  111.  
  112.     float F0 = 0.16 * pow(reflectance, 2.0);
  113.    
  114.         float result = PBR(Normal, ViewDirection, gDirectionalLight.Direction, roughness, F0);
  115.    
  116.     FragColor = vec4( result * Color , 1.0);
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement