gi.glsl 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  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 M_PI 3.141592
  6. #define SDFGI_MAX_CASCADES 8
  7. //set 0 for SDFGI and render buffers
  8. layout(set = 0, binding = 1) uniform texture3D sdf_cascades[SDFGI_MAX_CASCADES];
  9. layout(set = 0, binding = 2) uniform texture3D light_cascades[SDFGI_MAX_CASCADES];
  10. layout(set = 0, binding = 3) uniform texture3D aniso0_cascades[SDFGI_MAX_CASCADES];
  11. layout(set = 0, binding = 4) uniform texture3D aniso1_cascades[SDFGI_MAX_CASCADES];
  12. layout(set = 0, binding = 5) uniform texture3D occlusion_texture;
  13. layout(set = 0, binding = 6) uniform sampler linear_sampler;
  14. layout(set = 0, binding = 7) uniform sampler linear_sampler_with_mipmaps;
  15. struct ProbeCascadeData {
  16. vec3 position;
  17. float to_probe;
  18. ivec3 probe_world_offset;
  19. float to_cell; // 1/bounds * grid_size
  20. };
  21. layout(rgba16f, set = 0, binding = 9) uniform restrict writeonly image2D ambient_buffer;
  22. layout(rgba16f, set = 0, binding = 10) uniform restrict writeonly image2D reflection_buffer;
  23. layout(set = 0, binding = 11) uniform texture2DArray lightprobe_texture;
  24. layout(set = 0, binding = 12) uniform texture2D depth_buffer;
  25. layout(set = 0, binding = 13) uniform texture2D normal_roughness_buffer;
  26. layout(set = 0, binding = 14) uniform utexture2D giprobe_buffer;
  27. layout(set = 0, binding = 15, std140) uniform SDFGI {
  28. vec3 grid_size;
  29. uint max_cascades;
  30. bool use_occlusion;
  31. int probe_axis_size;
  32. float probe_to_uvw;
  33. float normal_bias;
  34. vec3 lightprobe_tex_pixel_size;
  35. float energy;
  36. vec3 lightprobe_uv_offset;
  37. float y_mult;
  38. vec3 occlusion_clamp;
  39. uint pad3;
  40. vec3 occlusion_renormalize;
  41. uint pad4;
  42. vec3 cascade_probe_size;
  43. uint pad5;
  44. ProbeCascadeData cascades[SDFGI_MAX_CASCADES];
  45. }
  46. sdfgi;
  47. #define MAX_GI_PROBES 8
  48. struct GIProbeData {
  49. mat4 xform;
  50. vec3 bounds;
  51. float dynamic_range;
  52. float bias;
  53. float normal_bias;
  54. bool blend_ambient;
  55. uint texture_slot;
  56. float anisotropy_strength;
  57. float ambient_occlusion;
  58. float ambient_occlusion_size;
  59. uint mipmaps;
  60. };
  61. layout(set = 0, binding = 16, std140) uniform GIProbes {
  62. GIProbeData data[MAX_GI_PROBES];
  63. }
  64. gi_probes;
  65. layout(set = 0, binding = 17) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
  66. layout(push_constant, binding = 0, std430) uniform Params {
  67. ivec2 screen_size;
  68. float z_near;
  69. float z_far;
  70. vec4 proj_info;
  71. vec3 ao_color;
  72. uint max_giprobes;
  73. bool high_quality_vct;
  74. bool orthogonal;
  75. uint pad[2];
  76. mat3x4 cam_rotation;
  77. }
  78. params;
  79. vec2 octahedron_wrap(vec2 v) {
  80. vec2 signVal;
  81. signVal.x = v.x >= 0.0 ? 1.0 : -1.0;
  82. signVal.y = v.y >= 0.0 ? 1.0 : -1.0;
  83. return (1.0 - abs(v.yx)) * signVal;
  84. }
  85. vec2 octahedron_encode(vec3 n) {
  86. // https://twitter.com/Stubbesaurus/status/937994790553227264
  87. n /= (abs(n.x) + abs(n.y) + abs(n.z));
  88. n.xy = n.z >= 0.0 ? n.xy : octahedron_wrap(n.xy);
  89. n.xy = n.xy * 0.5 + 0.5;
  90. return n.xy;
  91. }
  92. vec4 blend_color(vec4 src, vec4 dst) {
  93. vec4 res;
  94. float sa = 1.0 - src.a;
  95. res.a = dst.a * sa + src.a;
  96. if (res.a == 0.0) {
  97. res.rgb = vec3(0);
  98. } else {
  99. res.rgb = (dst.rgb * dst.a * sa + src.rgb * src.a) / res.a;
  100. }
  101. return res;
  102. }
  103. vec3 reconstruct_position(ivec2 screen_pos) {
  104. vec3 pos;
  105. pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r;
  106. pos.z = pos.z * 2.0 - 1.0;
  107. if (params.orthogonal) {
  108. pos.z = ((pos.z + (params.z_far + params.z_near) / (params.z_far - params.z_near)) * (params.z_far - params.z_near)) / 2.0;
  109. } else {
  110. pos.z = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - pos.z * (params.z_far - params.z_near));
  111. }
  112. pos.z = -pos.z;
  113. pos.xy = vec2(screen_pos) * params.proj_info.xy + params.proj_info.zw;
  114. if (!params.orthogonal) {
  115. pos.xy *= pos.z;
  116. }
  117. return pos;
  118. }
  119. void sdfgi_probe_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal, vec3 cam_specular_normal, float roughness, out vec3 diffuse_light, out vec3 specular_light) {
  120. cascade_pos += cam_normal * sdfgi.normal_bias;
  121. vec3 base_pos = floor(cascade_pos);
  122. //cascade_pos += mix(vec3(0.0),vec3(0.01),lessThan(abs(cascade_pos-base_pos),vec3(0.01))) * cam_normal;
  123. ivec3 probe_base_pos = ivec3(base_pos);
  124. vec4 diffuse_accum = vec4(0.0);
  125. vec3 specular_accum;
  126. ivec3 tex_pos = ivec3(probe_base_pos.xy, int(cascade));
  127. tex_pos.x += probe_base_pos.z * sdfgi.probe_axis_size;
  128. tex_pos.xy = tex_pos.xy * (SDFGI_OCT_SIZE + 2) + ivec2(1);
  129. vec3 diffuse_posf = (vec3(tex_pos) + vec3(octahedron_encode(cam_normal) * float(SDFGI_OCT_SIZE), 0.0)) * sdfgi.lightprobe_tex_pixel_size;
  130. vec3 specular_posf = (vec3(tex_pos) + vec3(octahedron_encode(cam_specular_normal) * float(SDFGI_OCT_SIZE), 0.0)) * sdfgi.lightprobe_tex_pixel_size;
  131. specular_accum = vec3(0.0);
  132. vec4 light_accum = vec4(0.0);
  133. float weight_accum = 0.0;
  134. for (uint j = 0; j < 8; j++) {
  135. ivec3 offset = (ivec3(j) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1);
  136. ivec3 probe_posi = probe_base_pos;
  137. probe_posi += offset;
  138. // Compute weight
  139. vec3 probe_pos = vec3(probe_posi);
  140. vec3 probe_to_pos = cascade_pos - probe_pos;
  141. vec3 probe_dir = normalize(-probe_to_pos);
  142. vec3 trilinear = vec3(1.0) - abs(probe_to_pos);
  143. float weight = trilinear.x * trilinear.y * trilinear.z * max(0.005, dot(cam_normal, probe_dir));
  144. // Compute lightprobe occlusion
  145. if (sdfgi.use_occlusion) {
  146. ivec3 occ_indexv = abs((sdfgi.cascades[cascade].probe_world_offset + probe_posi) & ivec3(1, 1, 1)) * ivec3(1, 2, 4);
  147. vec4 occ_mask = mix(vec4(0.0), vec4(1.0), equal(ivec4(occ_indexv.x | occ_indexv.y), ivec4(0, 1, 2, 3)));
  148. vec3 occ_pos = clamp(cascade_pos, probe_pos - sdfgi.occlusion_clamp, probe_pos + sdfgi.occlusion_clamp) * sdfgi.probe_to_uvw;
  149. occ_pos.z += float(cascade);
  150. if (occ_indexv.z != 0) { //z bit is on, means index is >=4, so make it switch to the other half of textures
  151. occ_pos.x += 1.0;
  152. }
  153. occ_pos *= sdfgi.occlusion_renormalize;
  154. float occlusion = dot(textureLod(sampler3D(occlusion_texture, linear_sampler), occ_pos, 0.0), occ_mask);
  155. weight *= max(occlusion, 0.01);
  156. }
  157. // Compute lightprobe texture position
  158. vec3 diffuse;
  159. vec3 pos_uvw = diffuse_posf;
  160. pos_uvw.xy += vec2(offset.xy) * sdfgi.lightprobe_uv_offset.xy;
  161. pos_uvw.x += float(offset.z) * sdfgi.lightprobe_uv_offset.z;
  162. diffuse = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0).rgb;
  163. diffuse_accum += vec4(diffuse * weight, weight);
  164. {
  165. vec3 specular = vec3(0.0);
  166. vec3 pos_uvw = specular_posf;
  167. pos_uvw.xy += vec2(offset.xy) * sdfgi.lightprobe_uv_offset.xy;
  168. pos_uvw.x += float(offset.z) * sdfgi.lightprobe_uv_offset.z;
  169. if (roughness < 0.99) {
  170. specular = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw + vec3(0, 0, float(sdfgi.max_cascades)), 0.0).rgb;
  171. }
  172. if (roughness > 0.2) {
  173. specular = mix(specular, textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0).rgb, (roughness - 0.2) * 1.25);
  174. }
  175. specular_accum += specular * weight;
  176. }
  177. }
  178. if (diffuse_accum.a > 0.0) {
  179. diffuse_accum.rgb /= diffuse_accum.a;
  180. }
  181. diffuse_light = diffuse_accum.rgb;
  182. if (diffuse_accum.a > 0.0) {
  183. specular_accum /= diffuse_accum.a;
  184. }
  185. specular_light = specular_accum;
  186. }
  187. void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, out vec4 ambient_light, out vec4 reflection_light) {
  188. //make vertex orientation the world one, but still align to camera
  189. vertex.y *= sdfgi.y_mult;
  190. normal.y *= sdfgi.y_mult;
  191. reflection.y *= sdfgi.y_mult;
  192. //renormalize
  193. normal = normalize(normal);
  194. reflection = normalize(reflection);
  195. vec3 cam_pos = vertex;
  196. vec3 cam_normal = normal;
  197. vec4 light_accum = vec4(0.0);
  198. float weight_accum = 0.0;
  199. vec4 light_blend_accum = vec4(0.0);
  200. float weight_blend_accum = 0.0;
  201. float blend = -1.0;
  202. // helper constants, compute once
  203. uint cascade = 0xFFFFFFFF;
  204. vec3 cascade_pos;
  205. vec3 cascade_normal;
  206. for (uint i = 0; i < sdfgi.max_cascades; i++) {
  207. cascade_pos = (cam_pos - sdfgi.cascades[i].position) * sdfgi.cascades[i].to_probe;
  208. if (any(lessThan(cascade_pos, vec3(0.0))) || any(greaterThanEqual(cascade_pos, sdfgi.cascade_probe_size))) {
  209. continue; //skip cascade
  210. }
  211. cascade = i;
  212. break;
  213. }
  214. if (cascade < SDFGI_MAX_CASCADES) {
  215. ambient_light = vec4(0, 0, 0, 1);
  216. reflection_light = vec4(0, 0, 0, 1);
  217. float blend;
  218. vec3 diffuse, specular;
  219. sdfgi_probe_process(cascade, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse, specular);
  220. {
  221. //process blend
  222. float blend_from = (float(sdfgi.probe_axis_size - 1) / 2.0) - 2.5;
  223. float blend_to = blend_from + 2.0;
  224. vec3 inner_pos = cam_pos * sdfgi.cascades[cascade].to_probe;
  225. float len = length(inner_pos);
  226. inner_pos = abs(normalize(inner_pos));
  227. len *= max(inner_pos.x, max(inner_pos.y, inner_pos.z));
  228. if (len >= blend_from) {
  229. blend = smoothstep(blend_from, blend_to, len);
  230. } else {
  231. blend = 0.0;
  232. }
  233. }
  234. if (blend > 0.0) {
  235. //blend
  236. if (cascade == sdfgi.max_cascades - 1) {
  237. ambient_light.a = 1.0 - blend;
  238. reflection_light.a = 1.0 - blend;
  239. } else {
  240. vec3 diffuse2, specular2;
  241. cascade_pos = (cam_pos - sdfgi.cascades[cascade + 1].position) * sdfgi.cascades[cascade + 1].to_probe;
  242. sdfgi_probe_process(cascade + 1, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse2, specular2);
  243. diffuse = mix(diffuse, diffuse2, blend);
  244. specular = mix(specular, specular2, blend);
  245. }
  246. }
  247. ambient_light.rgb = diffuse;
  248. if (roughness < 0.2) {
  249. vec3 pos_to_uvw = 1.0 / sdfgi.grid_size;
  250. vec4 light_accum = vec4(0.0);
  251. float blend_size = (sdfgi.grid_size.x / float(sdfgi.probe_axis_size - 1)) * 0.5;
  252. float radius_sizes[SDFGI_MAX_CASCADES];
  253. cascade = 0xFFFF;
  254. float base_distance = length(cam_pos);
  255. for (uint i = 0; i < sdfgi.max_cascades; i++) {
  256. radius_sizes[i] = (1.0 / sdfgi.cascades[i].to_cell) * (sdfgi.grid_size.x * 0.5 - blend_size);
  257. if (cascade == 0xFFFF && base_distance < radius_sizes[i]) {
  258. cascade = i;
  259. }
  260. }
  261. cascade = min(cascade, sdfgi.max_cascades - 1);
  262. float max_distance = radius_sizes[sdfgi.max_cascades - 1];
  263. vec3 ray_pos = cam_pos;
  264. vec3 ray_dir = reflection;
  265. {
  266. float prev_radius = cascade > 0 ? radius_sizes[cascade - 1] : 0.0;
  267. float base_blend = (base_distance - prev_radius) / (radius_sizes[cascade] - prev_radius);
  268. float bias = (1.0 + base_blend) * 1.1;
  269. vec3 abs_ray_dir = abs(ray_dir);
  270. //ray_pos += ray_dir * (bias / sdfgi.cascades[cascade].to_cell); //bias to avoid self occlusion
  271. ray_pos += (ray_dir * 1.0 / max(abs_ray_dir.x, max(abs_ray_dir.y, abs_ray_dir.z)) + cam_normal * 1.4) * bias / sdfgi.cascades[cascade].to_cell;
  272. }
  273. float softness = 0.2 + min(1.0, roughness * 5.0) * 4.0; //approximation to roughness so it does not seem like a hard fade
  274. uint i = 0;
  275. bool found = false;
  276. while (true) {
  277. if (length(ray_pos) >= max_distance || light_accum.a > 0.99) {
  278. break;
  279. }
  280. if (!found && i >= cascade && length(ray_pos) < radius_sizes[i]) {
  281. uint next_i = min(i + 1, sdfgi.max_cascades - 1);
  282. cascade = max(i, cascade); //never go down
  283. vec3 pos = ray_pos - sdfgi.cascades[i].position;
  284. pos *= sdfgi.cascades[i].to_cell * pos_to_uvw;
  285. float fdistance = textureLod(sampler3D(sdf_cascades[i], linear_sampler), pos, 0.0).r * 255.0 - 1.1;
  286. vec4 hit_light = vec4(0.0);
  287. if (fdistance < softness) {
  288. hit_light.rgb = textureLod(sampler3D(light_cascades[i], linear_sampler), pos, 0.0).rgb;
  289. hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
  290. hit_light.a = clamp(1.0 - (fdistance / softness), 0.0, 1.0);
  291. hit_light.rgb *= hit_light.a;
  292. }
  293. fdistance /= sdfgi.cascades[i].to_cell;
  294. if (i < (sdfgi.max_cascades - 1)) {
  295. pos = ray_pos - sdfgi.cascades[next_i].position;
  296. pos *= sdfgi.cascades[next_i].to_cell * pos_to_uvw;
  297. float fdistance2 = textureLod(sampler3D(sdf_cascades[next_i], linear_sampler), pos, 0.0).r * 255.0 - 1.1;
  298. vec4 hit_light2 = vec4(0.0);
  299. if (fdistance2 < softness) {
  300. hit_light2.rgb = textureLod(sampler3D(light_cascades[next_i], linear_sampler), pos, 0.0).rgb;
  301. hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
  302. hit_light2.a = clamp(1.0 - (fdistance2 / softness), 0.0, 1.0);
  303. hit_light2.rgb *= hit_light2.a;
  304. }
  305. float prev_radius = i == 0 ? 0.0 : radius_sizes[max(0, i - 1)];
  306. float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0);
  307. fdistance2 /= sdfgi.cascades[next_i].to_cell;
  308. hit_light = mix(hit_light, hit_light2, blend);
  309. fdistance = mix(fdistance, fdistance2, blend);
  310. }
  311. light_accum += hit_light;
  312. ray_pos += ray_dir * fdistance;
  313. found = true;
  314. }
  315. i++;
  316. if (i == sdfgi.max_cascades) {
  317. i = 0;
  318. found = false;
  319. }
  320. }
  321. vec3 light = light_accum.rgb / max(light_accum.a, 0.00001);
  322. float alpha = min(1.0, light_accum.a);
  323. float b = min(1.0, roughness * 5.0);
  324. float sa = 1.0 - b;
  325. reflection_light.a = alpha * sa + b;
  326. if (reflection_light.a == 0) {
  327. specular = vec3(0.0);
  328. } else {
  329. specular = (light * alpha * sa + specular * b) / reflection_light.a;
  330. }
  331. }
  332. reflection_light.rgb = specular;
  333. ambient_light.rgb *= sdfgi.energy;
  334. reflection_light.rgb *= sdfgi.energy;
  335. } else {
  336. ambient_light = vec4(0);
  337. reflection_light = vec4(0);
  338. }
  339. }
  340. //standard voxel cone trace
  341. vec4 voxel_cone_trace(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) {
  342. float dist = p_bias;
  343. vec4 color = vec4(0.0);
  344. while (dist < max_distance && color.a < 0.95) {
  345. float diameter = max(1.0, 2.0 * tan_half_angle * dist);
  346. vec3 uvw_pos = (pos + dist * direction) * cell_size;
  347. float half_diameter = diameter * 0.5;
  348. //check if outside, then break
  349. if (any(greaterThan(abs(uvw_pos - 0.5), vec3(0.5f + half_diameter * cell_size)))) {
  350. break;
  351. }
  352. vec4 scolor = textureLod(sampler3D(probe, linear_sampler_with_mipmaps), uvw_pos, log2(diameter));
  353. float a = (1.0 - color.a);
  354. color += a * scolor;
  355. dist += half_diameter;
  356. }
  357. return color;
  358. }
  359. vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, float max_distance, float p_bias) {
  360. float dist = p_bias;
  361. vec4 color = vec4(0.0);
  362. float radius = max(0.5, dist);
  363. float lod_level = log2(radius * 2.0);
  364. while (dist < max_distance && color.a < 0.95) {
  365. vec3 uvw_pos = (pos + dist * direction) * cell_size;
  366. //check if outside, then break
  367. if (any(greaterThan(abs(uvw_pos - 0.5), vec3(0.5f + radius * cell_size)))) {
  368. break;
  369. }
  370. vec4 scolor = textureLod(sampler3D(probe, linear_sampler_with_mipmaps), uvw_pos, lod_level);
  371. lod_level += 1.0;
  372. float a = (1.0 - color.a);
  373. scolor *= a;
  374. color += scolor;
  375. dist += radius;
  376. radius = max(0.5, dist);
  377. }
  378. return color;
  379. }
  380. void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, inout vec4 out_spec, inout vec4 out_diff, inout float out_blend) {
  381. position = (gi_probes.data[index].xform * vec4(position, 1.0)).xyz;
  382. ref_vec = normalize((gi_probes.data[index].xform * vec4(ref_vec, 0.0)).xyz);
  383. normal = normalize((gi_probes.data[index].xform * vec4(normal, 0.0)).xyz);
  384. position += normal * gi_probes.data[index].normal_bias;
  385. //this causes corrupted pixels, i have no idea why..
  386. if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, gi_probes.data[index].bounds))))) {
  387. return;
  388. }
  389. mat3 dir_xform = mat3(gi_probes.data[index].xform) * normal_xform;
  390. vec3 blendv = abs(position / gi_probes.data[index].bounds * 2.0 - 1.0);
  391. float blend = clamp(1.0 - max(blendv.x, max(blendv.y, blendv.z)), 0.0, 1.0);
  392. //float blend=1.0;
  393. float max_distance = length(gi_probes.data[index].bounds);
  394. vec3 cell_size = 1.0 / gi_probes.data[index].bounds;
  395. //irradiance
  396. vec4 light = vec4(0.0);
  397. if (params.high_quality_vct) {
  398. const uint cone_dir_count = 6;
  399. vec3 cone_dirs[cone_dir_count] = vec3[](
  400. vec3(0.0, 0.0, 1.0),
  401. vec3(0.866025, 0.0, 0.5),
  402. vec3(0.267617, 0.823639, 0.5),
  403. vec3(-0.700629, 0.509037, 0.5),
  404. vec3(-0.700629, -0.509037, 0.5),
  405. vec3(0.267617, -0.823639, 0.5));
  406. float cone_weights[cone_dir_count] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15);
  407. float cone_angle_tan = 0.577;
  408. for (uint i = 0; i < cone_dir_count; i++) {
  409. vec3 dir = normalize(dir_xform * cone_dirs[i]);
  410. light += cone_weights[i] * voxel_cone_trace(gi_probe_textures[index], cell_size, position, dir, cone_angle_tan, max_distance, gi_probes.data[index].bias);
  411. }
  412. } else {
  413. const uint cone_dir_count = 4;
  414. vec3 cone_dirs[cone_dir_count] = vec3[](
  415. vec3(0.707107, 0.0, 0.707107),
  416. vec3(0.0, 0.707107, 0.707107),
  417. vec3(-0.707107, 0.0, 0.707107),
  418. vec3(0.0, -0.707107, 0.707107));
  419. float cone_weights[cone_dir_count] = float[](0.25, 0.25, 0.25, 0.25);
  420. for (int i = 0; i < cone_dir_count; i++) {
  421. vec3 dir = normalize(dir_xform * cone_dirs[i]);
  422. light += cone_weights[i] * voxel_cone_trace_45_degrees(gi_probe_textures[index], cell_size, position, dir, max_distance, gi_probes.data[index].bias);
  423. }
  424. }
  425. if (gi_probes.data[index].ambient_occlusion > 0.001) {
  426. float size = 1.0 + gi_probes.data[index].ambient_occlusion_size * 7.0;
  427. float taps, blend;
  428. blend = modf(size, taps);
  429. float ao = 0.0;
  430. for (float i = 1.0; i <= taps; i++) {
  431. vec3 ofs = (position + normal * (i * 0.5 + 1.0)) * cell_size;
  432. ao += textureLod(sampler3D(gi_probe_textures[index], linear_sampler_with_mipmaps), ofs, i - 1.0).a * i;
  433. }
  434. if (blend > 0.001) {
  435. vec3 ofs = (position + normal * ((taps + 1.0) * 0.5 + 1.0)) * cell_size;
  436. ao += textureLod(sampler3D(gi_probe_textures[index], linear_sampler_with_mipmaps), ofs, taps).a * (taps + 1.0) * blend;
  437. }
  438. ao = 1.0 - min(1.0, ao);
  439. light.rgb = mix(params.ao_color, light.rgb, mix(1.0, ao, gi_probes.data[index].ambient_occlusion));
  440. }
  441. light.rgb *= gi_probes.data[index].dynamic_range;
  442. if (!gi_probes.data[index].blend_ambient) {
  443. light.a = 1.0;
  444. }
  445. out_diff += light * blend;
  446. //radiance
  447. vec4 irr_light = voxel_cone_trace(gi_probe_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, gi_probes.data[index].bias);
  448. irr_light.rgb *= gi_probes.data[index].dynamic_range;
  449. if (!gi_probes.data[index].blend_ambient) {
  450. irr_light.a = 1.0;
  451. }
  452. out_spec += irr_light * blend;
  453. out_blend += blend;
  454. }
  455. vec4 fetch_normal_and_roughness(ivec2 pos) {
  456. vec4 normal_roughness = texelFetch(sampler2D(normal_roughness_buffer, linear_sampler), pos, 0);
  457. normal_roughness.xyz = normalize(normal_roughness.xyz * 2.0 - 1.0);
  458. return normal_roughness;
  459. }
  460. void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 reflection_light) {
  461. vec4 normal_roughness = fetch_normal_and_roughness(pos);
  462. vec3 normal = normal_roughness.xyz;
  463. if (normal.length() > 0.5) {
  464. //valid normal, can do GI
  465. float roughness = normal_roughness.w;
  466. vertex = mat3(params.cam_rotation) * vertex;
  467. normal = normalize(mat3(params.cam_rotation) * normal);
  468. vec3 reflection = normalize(reflect(normalize(vertex), normal));
  469. #ifdef USE_SDFGI
  470. sdfgi_process(vertex, normal, reflection, roughness, ambient_light, reflection_light);
  471. #endif
  472. #ifdef USE_GIPROBES
  473. {
  474. uvec2 giprobe_tex = texelFetch(usampler2D(giprobe_buffer, linear_sampler), pos, 0).rg;
  475. roughness *= roughness;
  476. //find arbitrary tangent and bitangent, then build a matrix
  477. vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
  478. vec3 tangent = normalize(cross(v0, normal));
  479. vec3 bitangent = normalize(cross(tangent, normal));
  480. mat3 normal_mat = mat3(tangent, bitangent, normal);
  481. vec4 amb_accum = vec4(0.0);
  482. vec4 spec_accum = vec4(0.0);
  483. float blend_accum = 0.0;
  484. for (uint i = 0; i < params.max_giprobes; i++) {
  485. if (any(equal(uvec2(i), giprobe_tex))) {
  486. gi_probe_compute(i, vertex, normal, reflection, normal_mat, roughness, spec_accum, amb_accum, blend_accum);
  487. }
  488. }
  489. if (blend_accum > 0.0) {
  490. amb_accum /= blend_accum;
  491. spec_accum /= blend_accum;
  492. }
  493. #ifdef USE_SDFGI
  494. reflection_light = blend_color(spec_accum, reflection_light);
  495. ambient_light = blend_color(amb_accum, ambient_light);
  496. #else
  497. reflection_light = spec_accum;
  498. ambient_light = amb_accum;
  499. #endif
  500. }
  501. #endif
  502. }
  503. }
  504. void main() {
  505. ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
  506. #ifdef MODE_HALF_RES
  507. pos <<= 1;
  508. #endif
  509. if (any(greaterThanEqual(pos, params.screen_size))) { //too large, do nothing
  510. return;
  511. }
  512. vec4 ambient_light = vec4(0.0);
  513. vec4 reflection_light = vec4(0.0);
  514. vec3 vertex = reconstruct_position(pos);
  515. vertex.y = -vertex.y;
  516. process_gi(pos, vertex, ambient_light, reflection_light);
  517. #ifdef MODE_HALF_RES
  518. pos >>= 1;
  519. #endif
  520. imageStore(ambient_buffer, pos, ambient_light);
  521. imageStore(reflection_buffer, pos, reflection_light);
  522. }