智慧水务管理系统 - 精河县供水工程综合管理平台

ComputeIrradianceFS.glsl 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. uniform samplerCube u_radianceMap;
  2. in vec2 v_textureCoordinates;
  3. const float twoSqrtPi = 2.0 * sqrt(czm_pi);
  4. // Coutesy of https://www.ppsloan.org/publications/StupidSH36.pdf
  5. float computeShBasis(int index, vec3 s) {
  6. if (index == 0) { // l = 0, m = 0
  7. return 1.0 / twoSqrtPi;
  8. }
  9. if (index == 1) { // l = 1, m = -1
  10. return -sqrt(3.0) * s.y / twoSqrtPi;
  11. }
  12. if (index == 2) { // l = 1, m = 0
  13. return sqrt(3.0) * s.z / twoSqrtPi;
  14. }
  15. if (index == 3) { // l = 1, m = 1
  16. return -sqrt(3.0) * s.x / twoSqrtPi;
  17. }
  18. if (index == 4) { // l = 2, m = -2
  19. return sqrt(15.0) * s.y * s.x / twoSqrtPi;
  20. }
  21. if (index == 5) { // l = 2, m = -1
  22. return -sqrt(15.0) * s.y * s.z / twoSqrtPi;
  23. }
  24. if (index == 6) { // l = 2, m = 0
  25. return sqrt(5.0) * (3.0 * s.z * s.z - 1.0) / 2.0 / twoSqrtPi;
  26. }
  27. if (index == 7) { // l = 2, m = 1
  28. return -sqrt(15.0) * s.x * s.z / twoSqrtPi;
  29. }
  30. if (index == 8) { // l = 2, m = 2
  31. return sqrt(15.0) * (s.x * s.x - s.y * s.y) / 2.0 / twoSqrtPi;
  32. }
  33. return 0.0;
  34. }
  35. float vdcRadicalInverse(int i)
  36. {
  37. float r;
  38. float base = 2.0;
  39. float value = 0.0;
  40. float invBase = 1.0 / base;
  41. float invBi = invBase;
  42. for (int x = 0; x < 100; x++)
  43. {
  44. if (i <= 0)
  45. {
  46. break;
  47. }
  48. r = mod(float(i), base);
  49. value += r * invBi;
  50. invBi *= invBase;
  51. i = int(float(i) * invBase);
  52. }
  53. return value;
  54. }
  55. vec2 hammersley2D(int i, int N)
  56. {
  57. return vec2(float(i) / float(N), vdcRadicalInverse(i));
  58. }
  59. // Sample count is relatively low for the sake of performance, but should still be enough to capture directionality needed for third-order harmonics
  60. const int samples = 256;
  61. const float solidAngle = 1.0 / float(samples);
  62. void main() {
  63. // Get the current coefficient based on the uv
  64. vec2 uv = v_textureCoordinates.xy * 3.0;
  65. int coefficientIndex = int(floor(uv.y) * 3.0 + floor(uv.x));
  66. for (int i = 0; i < samples; ++i) {
  67. vec2 xi = hammersley2D(i, samples);
  68. float phi = czm_twoPi * xi.x;
  69. float cosTheta = 1.0 - 2.0 * sqrt(1.0 - xi.y * xi.y);
  70. float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
  71. vec3 direction = normalize(vec3(sinTheta * cos(phi), cosTheta, sinTheta * sin(phi)));
  72. // Generate the spherical harmonics basis from the direction
  73. float Ylm = computeShBasis(coefficientIndex, direction);
  74. vec3 lookupDirection = -direction.xyz;
  75. lookupDirection.z = -lookupDirection.z;
  76. vec4 color = czm_textureCube(u_radianceMap, lookupDirection, 0.0);
  77. // Use the relevant function for this coefficient
  78. out_FragColor += Ylm * color * solidAngle * sinTheta;
  79. }
  80. }