gi.frag 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // From http://graphics.cs.aueb.gr/graphics/research_illumination.html
  2. // "Real-Time Diffuse Global Illumination Using Radiance Hints"
  3. // paper and shader code
  4. uniform sampler2D ntex;
  5. uniform sampler2D dtex;
  6. uniform sampler3D SHR;
  7. uniform sampler3D SHG;
  8. uniform sampler3D SHB;
  9. uniform vec3 extents;
  10. uniform mat4 RHMatrix;
  11. uniform mat4 InvRHMatrix;
  12. vec4 SHBasis (const in vec3 dir)
  13. {
  14. float L00 = 0.282095;
  15. float L1_1 = 0.488603 * dir.y;
  16. float L10 = 0.488603 * dir.z;
  17. float L11 = 0.488603 * dir.x;
  18. return vec4 (L11, L1_1, L10, L00);
  19. }
  20. vec3 SH2RGB (in vec4 sh_r, in vec4 sh_g, in vec4 sh_b, in vec3 dir)
  21. {
  22. vec4 Y = vec4(1.023326*dir.x, 1.023326*dir.y, 1.023326*dir.z, 0.886226);
  23. return vec3 (dot(Y,sh_r), dot(Y,sh_g), dot(Y,sh_b));
  24. }
  25. out vec4 Diffuse;
  26. vec3 DecodeNormal(vec2 n);
  27. vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
  28. vec3 resolution = vec3(32, 16, 32);
  29. void main()
  30. {
  31. vec2 uv = gl_FragCoord.xy / screen;
  32. vec3 GI = vec3(0.);
  33. float depth = texture2D(dtex, uv).x;
  34. // Discard background fragments
  35. if (depth==1.0) discard;
  36. vec4 pos_screen_space = getPosFromUVDepth(vec3(uv, depth), InverseProjectionMatrix);
  37. vec4 tmp = (InvRHMatrix * InverseViewMatrix * pos_screen_space);
  38. vec3 pos = tmp.xyz / tmp.w;
  39. vec3 normal_screen_space = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.));
  40. vec3 normal = (transpose(ViewMatrix) * vec4(normal_screen_space, 0.)).xyz;
  41. // Convert to grid coordinates
  42. vec3 uvw = .5 + 0.5 * pos / extents;
  43. if (uvw.x < 0. || uvw.x > 1. || uvw.y < 0. || uvw.y > 1. || uvw.z < 0. || uvw.z > 1.) discard;
  44. // Sample the RH volume at 4 locations, one directly above the shaded point,
  45. // three on a ring 80degs away from the normal direction.
  46. vec3 rnd = vec3(0,0,0);
  47. // Generate the sample locations
  48. vec3 v_rand = vec3(0.5);
  49. vec3 tangent = normalize(cross(normal, v_rand));
  50. vec3 bitangent = cross(normal, tangent);
  51. vec3 D[4];
  52. D[0] = vec3(1.0,0.0,0.0);
  53. int i;
  54. for (i=1; i<4; i++)
  55. {
  56. D[i] = vec3(0.1, 0.8*cos((rnd.x*1.5+i)*6.2832/3.0), 0.8*sin((rnd.x*1.5+i)*6.2832/3.0));
  57. D[i] = normalize(D[i]);
  58. }
  59. for (i=0; i<4; i++)
  60. {
  61. vec3 SampleDir = normal * D[i].x + tangent * D[i].y + bitangent *D[i].z;
  62. vec3 SampleOffset = (0.5 * normal + SampleDir) / resolution;
  63. vec3 uvw_new = uvw + SampleOffset;
  64. vec4 IncidentSHR = texture(SHR, uvw_new);
  65. vec4 IncidentSHG = texture(SHG, uvw_new);
  66. vec4 IncidentSHB = texture(SHB, uvw_new);
  67. GI += SH2RGB(IncidentSHR, IncidentSHG, IncidentSHB, -normal);
  68. }
  69. GI /= 4;
  70. Diffuse = max(16. * vec4(GI, 1.), vec4(0.));
  71. }