No Description

pbr.frag 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #version 450
  2. layout (location = 0) in vec3 inWorldPos;
  3. layout (location = 1) in vec3 inNormal;
  4. layout (binding = 0) uniform UBO
  5. {
  6. mat4 projection;
  7. mat4 model;
  8. mat4 view;
  9. vec3 camPos;
  10. } ubo;
  11. layout (binding = 1) uniform UBOShared {
  12. vec4 lights[4];
  13. } uboParams;
  14. layout (location = 0) out vec4 outColor;
  15. layout(push_constant) uniform PushConsts {
  16. layout(offset = 12) float roughness;
  17. layout(offset = 16) float metallic;
  18. layout(offset = 20) float r;
  19. layout(offset = 24) float g;
  20. layout(offset = 28) float b;
  21. } material;
  22. const float PI = 3.14159265359;
  23. //#define ROUGHNESS_PATTERN 1
  24. vec3 materialcolor()
  25. {
  26. return vec3(material.r, material.g, material.b);
  27. }
  28. // Normal Distribution function --------------------------------------
  29. float D_GGX(float dotNH, float roughness)
  30. {
  31. float alpha = roughness * roughness;
  32. float alpha2 = alpha * alpha;
  33. float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
  34. return (alpha2)/(PI * denom*denom);
  35. }
  36. // Geometric Shadowing function --------------------------------------
  37. float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
  38. {
  39. float r = (roughness + 1.0);
  40. float k = (r*r) / 8.0;
  41. float GL = dotNL / (dotNL * (1.0 - k) + k);
  42. float GV = dotNV / (dotNV * (1.0 - k) + k);
  43. return GL * GV;
  44. }
  45. // Fresnel function ----------------------------------------------------
  46. vec3 F_Schlick(float cosTheta, float metallic)
  47. {
  48. vec3 F0 = mix(vec3(0.04), materialcolor(), metallic); // * material.specular
  49. vec3 F = F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
  50. return F;
  51. }
  52. // Specular BRDF composition --------------------------------------------
  53. vec3 BRDF(vec3 L, vec3 V, vec3 N, float metallic, float roughness)
  54. {
  55. // Precalculate vectors and dot products
  56. vec3 H = normalize (V + L);
  57. float dotNV = clamp(dot(N, V), 0.0, 1.0);
  58. float dotNL = clamp(dot(N, L), 0.0, 1.0);
  59. float dotLH = clamp(dot(L, H), 0.0, 1.0);
  60. float dotNH = clamp(dot(N, H), 0.0, 1.0);
  61. // Light color fixed
  62. vec3 lightColor = vec3(1.0);
  63. vec3 color = vec3(0.0);
  64. if (dotNL > 0.0)
  65. {
  66. float rroughness = max(0.05, roughness);
  67. // D = Normal distribution (Distribution of the microfacets)
  68. float D = D_GGX(dotNH, roughness);
  69. // G = Geometric shadowing term (Microfacets shadowing)
  70. float G = G_SchlicksmithGGX(dotNL, dotNV, roughness);
  71. // F = Fresnel factor (Reflectance depending on angle of incidence)
  72. vec3 F = F_Schlick(dotNV, metallic);
  73. vec3 spec = D * F * G / (4.0 * dotNL * dotNV);
  74. color += spec * dotNL * lightColor;
  75. }
  76. return color;
  77. }
  78. // ----------------------------------------------------------------------------
  79. void main()
  80. {
  81. vec3 N = normalize(inNormal);
  82. vec3 V = normalize(ubo.camPos - inWorldPos);
  83. float roughness = material.roughness;
  84. // Add striped pattern to roughness based on vertex position
  85. #ifdef ROUGHNESS_PATTERN
  86. roughness = max(roughness, step(fract(inWorldPos.y * 2.02), 0.5));
  87. #endif
  88. // Specular contribution
  89. vec3 Lo = vec3(0.0);
  90. for (int i = 0; i < uboParams.lights.length(); i++) {
  91. vec3 L = normalize(uboParams.lights[i].xyz - inWorldPos);
  92. Lo += BRDF(L, V, N, material.metallic, roughness);
  93. };
  94. // Combine with ambient
  95. vec3 color = materialcolor() * 0.02;
  96. color += Lo;
  97. // Gamma correct
  98. color = pow(color, vec3(0.4545));
  99. outColor = vec4(color, 1.0);
  100. }