sdfgi_debug.glsl 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #[compute]
  2. #version 450
  3. VERSION_DEFINES
  4. layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
  5. #define MAX_CASCADES 8
  6. layout(set = 0, binding = 1) uniform texture3D sdf_cascades[MAX_CASCADES];
  7. layout(set = 0, binding = 2) uniform texture3D light_cascades[MAX_CASCADES];
  8. layout(set = 0, binding = 3) uniform texture3D aniso0_cascades[MAX_CASCADES];
  9. layout(set = 0, binding = 4) uniform texture3D aniso1_cascades[MAX_CASCADES];
  10. layout(set = 0, binding = 5) uniform texture3D occlusion_texture;
  11. layout(set = 0, binding = 8) uniform sampler linear_sampler;
  12. struct CascadeData {
  13. vec3 offset; //offset of (0,0,0) in world coordinates
  14. float to_cell; // 1/bounds * grid_size
  15. ivec3 probe_world_offset;
  16. uint pad;
  17. };
  18. layout(set = 0, binding = 9, std140) uniform Cascades {
  19. CascadeData data[MAX_CASCADES];
  20. }
  21. cascades;
  22. layout(rgba16f, set = 0, binding = 10) uniform restrict writeonly image2D screen_buffer;
  23. layout(set = 0, binding = 11) uniform texture2DArray lightprobe_texture;
  24. layout(push_constant, binding = 0, std430) uniform Params {
  25. vec3 grid_size;
  26. uint max_cascades;
  27. ivec2 screen_size;
  28. bool use_occlusion;
  29. float y_mult;
  30. vec3 cam_extent;
  31. int probe_axis_size;
  32. mat4 cam_transform;
  33. }
  34. params;
  35. vec3 linear_to_srgb(vec3 color) {
  36. //if going to srgb, clamp from 0 to 1.
  37. color = clamp(color, vec3(0.0), vec3(1.0));
  38. const vec3 a = vec3(0.055f);
  39. return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
  40. }
  41. vec2 octahedron_wrap(vec2 v) {
  42. vec2 signVal;
  43. signVal.x = v.x >= 0.0 ? 1.0 : -1.0;
  44. signVal.y = v.y >= 0.0 ? 1.0 : -1.0;
  45. return (1.0 - abs(v.yx)) * signVal;
  46. }
  47. vec2 octahedron_encode(vec3 n) {
  48. // https://twitter.com/Stubbesaurus/status/937994790553227264
  49. n /= (abs(n.x) + abs(n.y) + abs(n.z));
  50. n.xy = n.z >= 0.0 ? n.xy : octahedron_wrap(n.xy);
  51. n.xy = n.xy * 0.5 + 0.5;
  52. return n.xy;
  53. }
  54. void main() {
  55. // Pixel being shaded
  56. ivec2 screen_pos = ivec2(gl_GlobalInvocationID.xy);
  57. if (any(greaterThanEqual(screen_pos, params.screen_size))) { //too large, do nothing
  58. return;
  59. }
  60. vec3 ray_pos;
  61. vec3 ray_dir;
  62. {
  63. ray_pos = params.cam_transform[3].xyz;
  64. ray_dir.xy = params.cam_extent.xy * ((vec2(screen_pos) / vec2(params.screen_size)) * 2.0 - 1.0);
  65. ray_dir.z = params.cam_extent.z;
  66. ray_dir = normalize(mat3(params.cam_transform) * ray_dir);
  67. }
  68. ray_pos.y *= params.y_mult;
  69. ray_dir.y *= params.y_mult;
  70. ray_dir = normalize(ray_dir);
  71. vec3 pos_to_uvw = 1.0 / params.grid_size;
  72. vec3 light = vec3(0.0);
  73. float blend = 0.0;
  74. #if 1
  75. // No interpolation
  76. vec3 inv_dir = 1.0 / ray_dir;
  77. float rough = 0.5;
  78. bool hit = false;
  79. for (uint i = 0; i < params.max_cascades; i++) {
  80. //convert to local bounds
  81. vec3 pos = ray_pos - cascades.data[i].offset;
  82. pos *= cascades.data[i].to_cell;
  83. // Should never happen for debug, since we start mostly at the bounds center,
  84. // but add anyway.
  85. //if (any(lessThan(pos,vec3(0.0))) || any(greaterThanEqual(pos,params.grid_size))) {
  86. // continue; //already past bounds for this cascade, goto next
  87. //}
  88. //find maximum advance distance (until reaching bounds)
  89. vec3 t0 = -pos * inv_dir;
  90. vec3 t1 = (params.grid_size - pos) * inv_dir;
  91. vec3 tmax = max(t0, t1);
  92. float max_advance = min(tmax.x, min(tmax.y, tmax.z));
  93. float advance = 0.0;
  94. vec3 uvw;
  95. hit = false;
  96. while (advance < max_advance) {
  97. //read how much to advance from SDF
  98. uvw = (pos + ray_dir * advance) * pos_to_uvw;
  99. float distance = texture(sampler3D(sdf_cascades[i], linear_sampler), uvw).r * 255.0 - 1.7;
  100. if (distance < 0.001) {
  101. //consider hit
  102. hit = true;
  103. break;
  104. }
  105. advance += distance;
  106. }
  107. if (!hit) {
  108. pos += ray_dir * min(advance, max_advance);
  109. pos /= cascades.data[i].to_cell;
  110. pos += cascades.data[i].offset;
  111. ray_pos = pos;
  112. continue;
  113. }
  114. //compute albedo, emission and normal at hit point
  115. const float EPSILON = 0.001;
  116. vec3 hit_normal = normalize(vec3(
  117. texture(sampler3D(sdf_cascades[i], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[i], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r,
  118. texture(sampler3D(sdf_cascades[i], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[i], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r,
  119. texture(sampler3D(sdf_cascades[i], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[i], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r));
  120. vec3 hit_light = texture(sampler3D(light_cascades[i], linear_sampler), uvw).rgb;
  121. vec4 aniso0 = texture(sampler3D(aniso0_cascades[i], linear_sampler), uvw);
  122. vec3 hit_aniso0 = aniso0.rgb;
  123. vec3 hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[i], linear_sampler), uvw).rg);
  124. hit_light *= (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0)));
  125. light = hit_light;
  126. break;
  127. }
  128. #endif
  129. imageStore(screen_buffer, screen_pos, vec4(linear_to_srgb(light), 1.0));
  130. }