IrradianceSH.ankiprog 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <!--
  2. Copyright (C) 2009-2018, Panagiotis Christopoulos Charitos and contributors.
  3. All rights reserved.
  4. Code licensed under the BSD License.
  5. http://www.anki3d.org/LICENSE
  6. -->
  7. <shaderProgram>
  8. <shaders>
  9. <shader type="comp">
  10. <inputs>
  11. <input name="WORKGROUP_SIZE" type="uvec2" const="1"/>
  12. </inputs>
  13. <source><![CDATA[
  14. #include "shaders/Functions.glsl"
  15. layout(local_size_x = WORKGROUP_SIZE.x, local_size_y = WORKGROUP_SIZE.y, local_size_z = 1) in;
  16. struct PushConsts
  17. {
  18. uvec4 layerPad3;
  19. };
  20. ANKI_PUSH_CONSTANTS(PushConsts, u_regs);
  21. #define u_layer u_regs.layerPad3.x
  22. layout(ANKI_TEX_BINDING(0, 0)) uniform samplerCubeArray u_envTex;
  23. #define SHCoefficients vec4
  24. #define y00 x // Y l=0 m=0
  25. #define y1n1 y // Y l=1 m=-1
  26. #define y10 z // Y l=1 m=0
  27. #define y11 w // Y l=1 m=1
  28. layout(std140, ANKI_SS_BINDING(0, 0)) writeonly buffer _s0
  29. {
  30. SHCoefficients u_SH[];
  31. };
  32. #define u_SHr u_SH[u_layer * 3u + 0u]
  33. #define u_SHg u_SH[u_layer * 3u + 1u]
  34. #define u_SHb u_SH[u_layer * 3u + 2u]
  35. shared SHCoefficients s_scratch[3][WORKGROUP_SIZE.y * WORKGROUP_SIZE.x];
  36. SHCoefficients computeSHCoeffiecients(vec3 dir)
  37. {
  38. const float A = 0.282095;
  39. const float B = 0.488603;
  40. SHCoefficients sh;
  41. sh.y00 = A;
  42. sh.y1n1 = B * dir.y;
  43. sh.y10 = B * dir.z;
  44. sh.y11 = B * dir.x;
  45. return sh;
  46. }
  47. float areaElement(float x, float y)
  48. {
  49. return atan(x * y, sqrt(x * x + y * y + 1.0));
  50. }
  51. float cubeCoordSolidAngle(vec2 norm)
  52. {
  53. vec2 invSize = 1.0 / vec2(WORKGROUP_SIZE);
  54. vec2 v0 = norm - invSize;
  55. vec2 v1 = norm + invSize;
  56. return areaElement(v0.x, v0.y) - areaElement(v0.x, v1.y) - areaElement(v1.x, v0.y) + areaElement(v1.x, v1.y);
  57. }
  58. // Resolve the cube faces
  59. void initPass()
  60. {
  61. vec2 ndc = UV_TO_NDC(vec2(gl_LocalInvocationID.xy) / vec2(WORKGROUP_SIZE));
  62. SHCoefficients SHr = SHCoefficients(0.0);
  63. SHCoefficients SHg = SHCoefficients(0.0);
  64. SHCoefficients SHb = SHCoefficients(0.0);
  65. ANKI_LOOP for(uint face = 0u; face < 6u; ++face)
  66. {
  67. vec3 dir = getCubemapDirection(ndc, face);
  68. SHCoefficients sh = computeSHCoeffiecients(dir);
  69. vec3 rgb = textureLod(u_envTex, vec4(dir, u_layer), 10.0).rgb;
  70. #if 1
  71. rgb = mix(rgb, textureLod(u_envTex, vec4(-dir, u_layer), 10.0).rgb, 0.10);
  72. #endif
  73. SHr += rgb.r * sh;
  74. SHg += rgb.g * sh;
  75. SHb += rgb.b * sh;
  76. }
  77. float solidAngle = cubeCoordSolidAngle(ndc);
  78. uint idx = gl_LocalInvocationID.y * WORKGROUP_SIZE.x + gl_LocalInvocationID.x;
  79. s_scratch[0][idx] = SHr * solidAngle / PI;
  80. s_scratch[1][idx] = SHg * solidAngle / PI;
  81. s_scratch[2][idx] = SHb * solidAngle / PI;
  82. memoryBarrierShared();
  83. barrier();
  84. }
  85. // Reduce the result to a single vec4 per color component
  86. void reducePasses()
  87. {
  88. // Gather the results into one
  89. ANKI_UNROLL for(uint s = (WORKGROUP_SIZE.x * WORKGROUP_SIZE.y) / 2u; s > 0u; s >>= 1u)
  90. {
  91. if(gl_LocalInvocationIndex < s)
  92. {
  93. s_scratch[0][gl_LocalInvocationIndex] += s_scratch[0][gl_LocalInvocationIndex + s];
  94. s_scratch[1][gl_LocalInvocationIndex] += s_scratch[1][gl_LocalInvocationIndex + s];
  95. s_scratch[2][gl_LocalInvocationIndex] += s_scratch[2][gl_LocalInvocationIndex + s];
  96. }
  97. memoryBarrierShared();
  98. barrier();
  99. }
  100. }
  101. // Compute the final result
  102. void resolvePass()
  103. {
  104. if(gl_LocalInvocationIndex == 0)
  105. {
  106. u_SHr = s_scratch[0][0];
  107. u_SHg = s_scratch[1][0];
  108. u_SHb = s_scratch[2][0];
  109. }
  110. }
  111. void main()
  112. {
  113. initPass();
  114. reducePasses();
  115. resolvePass();
  116. /*if(u_layer == 0)
  117. u_SHr = u_SHg = u_SHb = vec4(1.0, 0.0, 0.0, 0.0);
  118. else if(u_layer == 1)
  119. u_SHr = u_SHg = u_SHb = vec4(0.0, 1.0, 0.0, 0.0);
  120. else if(u_layer == 2)
  121. u_SHr = u_SHg = u_SHb = vec4(0.0, 0.0, 1.0, 0.0);
  122. else
  123. u_SHr = u_SHg = u_SHb = vec4(1.0, 0.0, 1.0, 0.0);*/
  124. /*u_SHr = vec4(1, 0, 1, 1);
  125. u_SHg = vec4(1, 0, 1, 1);
  126. u_SHb = vec4(1, 0, 1, 1);*/
  127. }
  128. ]]></source>
  129. </shader>
  130. </shaders>
  131. </shaderProgram>