cubemap_downsampler.glsl 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright 2016 Activision Publishing, Inc.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining
  4. // a copy of this software and associated documentation files (the "Software"),
  5. // to deal in the Software without restriction, including without limitation
  6. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  7. // and/or sell copies of the Software, and to permit persons to whom the Software
  8. // is furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in all
  11. // copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19. // SOFTWARE.
  20. #[compute]
  21. #version 450
  22. VERSION_DEFINES
  23. #define BLOCK_SIZE 8
  24. layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in;
  25. layout(set = 0, binding = 0) uniform samplerCube source_cubemap;
  26. layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly imageCube dest_cubemap;
  27. layout(push_constant, binding = 1, std430) uniform Params {
  28. uint face_size;
  29. }
  30. params;
  31. #define M_PI 3.14159265359
  32. void get_dir_0(out vec3 dir, in float u, in float v) {
  33. dir[0] = 1.0;
  34. dir[1] = v;
  35. dir[2] = -u;
  36. }
  37. void get_dir_1(out vec3 dir, in float u, in float v) {
  38. dir[0] = -1.0;
  39. dir[1] = v;
  40. dir[2] = u;
  41. }
  42. void get_dir_2(out vec3 dir, in float u, in float v) {
  43. dir[0] = u;
  44. dir[1] = 1.0;
  45. dir[2] = -v;
  46. }
  47. void get_dir_3(out vec3 dir, in float u, in float v) {
  48. dir[0] = u;
  49. dir[1] = -1.0;
  50. dir[2] = v;
  51. }
  52. void get_dir_4(out vec3 dir, in float u, in float v) {
  53. dir[0] = u;
  54. dir[1] = v;
  55. dir[2] = 1.0;
  56. }
  57. void get_dir_5(out vec3 dir, in float u, in float v) {
  58. dir[0] = -u;
  59. dir[1] = v;
  60. dir[2] = -1.0;
  61. }
  62. float calcWeight(float u, float v) {
  63. float val = u * u + v * v + 1.0;
  64. return val * sqrt(val);
  65. }
  66. void main() {
  67. uvec3 id = gl_GlobalInvocationID;
  68. uint face_size = params.face_size;
  69. if (id.x < face_size && id.y < face_size) {
  70. float inv_face_size = 1.0 / float(face_size);
  71. float u0 = (float(id.x) * 2.0 + 1.0 - 0.75) * inv_face_size - 1.0;
  72. float u1 = (float(id.x) * 2.0 + 1.0 + 0.75) * inv_face_size - 1.0;
  73. float v0 = (float(id.y) * 2.0 + 1.0 - 0.75) * -inv_face_size + 1.0;
  74. float v1 = (float(id.y) * 2.0 + 1.0 + 0.75) * -inv_face_size + 1.0;
  75. float weights[4];
  76. weights[0] = calcWeight(u0, v0);
  77. weights[1] = calcWeight(u1, v0);
  78. weights[2] = calcWeight(u0, v1);
  79. weights[3] = calcWeight(u1, v1);
  80. const float wsum = 0.5 / (weights[0] + weights[1] + weights[2] + weights[3]);
  81. for (int i = 0; i < 4; i++) {
  82. weights[i] = weights[i] * wsum + .125;
  83. }
  84. vec3 dir;
  85. vec4 color;
  86. switch (id.z) {
  87. case 0:
  88. get_dir_0(dir, u0, v0);
  89. color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
  90. get_dir_0(dir, u1, v0);
  91. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
  92. get_dir_0(dir, u0, v1);
  93. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
  94. get_dir_0(dir, u1, v1);
  95. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
  96. break;
  97. case 1:
  98. get_dir_1(dir, u0, v0);
  99. color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
  100. get_dir_1(dir, u1, v0);
  101. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
  102. get_dir_1(dir, u0, v1);
  103. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
  104. get_dir_1(dir, u1, v1);
  105. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
  106. break;
  107. case 2:
  108. get_dir_2(dir, u0, v0);
  109. color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
  110. get_dir_2(dir, u1, v0);
  111. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
  112. get_dir_2(dir, u0, v1);
  113. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
  114. get_dir_2(dir, u1, v1);
  115. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
  116. break;
  117. case 3:
  118. get_dir_3(dir, u0, v0);
  119. color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
  120. get_dir_3(dir, u1, v0);
  121. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
  122. get_dir_3(dir, u0, v1);
  123. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
  124. get_dir_3(dir, u1, v1);
  125. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
  126. break;
  127. case 4:
  128. get_dir_4(dir, u0, v0);
  129. color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
  130. get_dir_4(dir, u1, v0);
  131. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
  132. get_dir_4(dir, u0, v1);
  133. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
  134. get_dir_4(dir, u1, v1);
  135. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
  136. break;
  137. default:
  138. get_dir_5(dir, u0, v0);
  139. color = textureLod(source_cubemap, normalize(dir), 0.0) * weights[0];
  140. get_dir_5(dir, u1, v0);
  141. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[1];
  142. get_dir_5(dir, u0, v1);
  143. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[2];
  144. get_dir_5(dir, u1, v1);
  145. color += textureLod(source_cubemap, normalize(dir), 0.0) * weights[3];
  146. break;
  147. }
  148. imageStore(dest_cubemap, ivec3(id), color);
  149. }
  150. }