BrdfLutGeneratorFS.glsl 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. varying vec2 v_textureCoordinates;
  2. const float M_PI = 3.141592653589793;
  3. float vdcRadicalInverse(int i)
  4. {
  5. float r;
  6. float base = 2.0;
  7. float value = 0.0;
  8. float invBase = 1.0 / base;
  9. float invBi = invBase;
  10. for (int x = 0; x < 100; x++)
  11. {
  12. if (i <= 0)
  13. {
  14. break;
  15. }
  16. r = mod(float(i), base);
  17. value += r * invBi;
  18. invBi *= invBase;
  19. i = int(float(i) * invBase);
  20. }
  21. return value;
  22. }
  23. vec2 hammersley2D(int i, int N)
  24. {
  25. return vec2(float(i) / float(N), vdcRadicalInverse(i));
  26. }
  27. vec3 importanceSampleGGX(vec2 xi, float roughness, vec3 N)
  28. {
  29. float a = roughness * roughness;
  30. float phi = 2.0 * M_PI * xi.x;
  31. float cosTheta = sqrt((1.0 - xi.y) / (1.0 + (a * a - 1.0) * xi.y));
  32. float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
  33. vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
  34. vec3 upVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
  35. vec3 tangentX = normalize(cross(upVector, N));
  36. vec3 tangentY = cross(N, tangentX);
  37. return tangentX * H.x + tangentY * H.y + N * H.z;
  38. }
  39. float G1_Smith(float NdotV, float k)
  40. {
  41. return NdotV / (NdotV * (1.0 - k) + k);
  42. }
  43. float G_Smith(float roughness, float NdotV, float NdotL)
  44. {
  45. float k = roughness * roughness / 2.0;
  46. return G1_Smith(NdotV, k) * G1_Smith(NdotL, k);
  47. }
  48. vec2 integrateBrdf(float roughness, float NdotV)
  49. {
  50. vec3 V = vec3(sqrt(1.0 - NdotV * NdotV), 0.0, NdotV);
  51. float A = 0.0;
  52. float B = 0.0;
  53. const int NumSamples = 1024;
  54. for (int i = 0; i < NumSamples; i++)
  55. {
  56. vec2 xi = hammersley2D(i, NumSamples);
  57. vec3 H = importanceSampleGGX(xi, roughness, vec3(0.0, 0.0, 1.0));
  58. vec3 L = 2.0 * dot(V, H) * H - V;
  59. float NdotL = clamp(L.z, 0.0, 1.0);
  60. float NdotH = clamp(H.z, 0.0, 1.0);
  61. float VdotH = clamp(dot(V, H), 0.0, 1.0);
  62. if (NdotL > 0.0)
  63. {
  64. float G = G_Smith(roughness, NdotV, NdotL);
  65. float G_Vis = G * VdotH / (NdotH * NdotV);
  66. float Fc = pow(1.0 - VdotH, 5.0);
  67. A += (1.0 - Fc) * G_Vis;
  68. B += Fc * G_Vis;
  69. }
  70. }
  71. return vec2(A, B) / float(NumSamples);
  72. }
  73. void main()
  74. {
  75. gl_FragColor = vec4(integrateBrdf(v_textureCoordinates.y, v_textureCoordinates.x), 0.0, 1.0);
  76. }