conetrace.glsl 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #ifndef _CONETRACE_GLSL_
  2. #define _CONETRACE_GLSL_
  3. // References
  4. // https://github.com/Friduric/voxel-cone-tracing
  5. // https://github.com/Cigg/Voxel-Cone-Tracing
  6. // https://github.com/GreatBlambo/voxel_cone_tracing/
  7. // http://simonstechblog.blogspot.com/2013/01/implementing-voxel-cone-tracing.html
  8. // http://leifnode.com/2015/05/voxel-cone-traced-global-illumination/
  9. // http://www.seas.upenn.edu/%7Epcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf
  10. // https://research.nvidia.com/sites/default/files/publications/GIVoxels-pg2011-authors.pdf
  11. const ivec3 voxelgiResolution = ivec3(256, 256, 256);
  12. const vec3 voxelgiHalfExtents = vec3(1, 1, 1);
  13. const float voxelgiOcc = 1.0;
  14. const float voxelgiStep = 1.0;
  15. const float voxelgiRange = 2.0;
  16. const float MAX_DISTANCE = 1.73205080757 * voxelgiRange;
  17. const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep;
  18. uniform float coneOffset;
  19. uniform float coneAperture;
  20. vec3 tangent(const vec3 n) {
  21. vec3 t1 = cross(n, vec3(0, 0, 1));
  22. vec3 t2 = cross(n, vec3(0, 1, 0));
  23. if (length(t1) > length(t2)) return normalize(t1);
  24. else return normalize(t2);
  25. }
  26. float traceConeAO(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float maxDist) {
  27. dir = normalize(dir);
  28. float sampleCol = 0.0;
  29. float dist = 1.5 * VOXEL_SIZE * coneOffset;
  30. // float dist = (0.02 + 0.02 * (1.0 - dot(dir, normal)) ) * coneOffset;
  31. float diam = dist * aperture;
  32. vec3 samplePos;
  33. while (sampleCol < 1.0 && dist < maxDist) {
  34. samplePos = dir * dist + origin;
  35. float mip = max(log2(diam * voxelgiResolution.x), 0);
  36. float mipSample = textureLod(voxels, samplePos * 0.5 + vec3(0.5), mip).r;
  37. sampleCol += (1 - sampleCol) * mipSample;
  38. dist += max(diam / 2, VOXEL_SIZE);
  39. diam = dist * aperture;
  40. }
  41. return sampleCol;
  42. }
  43. float traceShadow(sampler3D voxels, const vec3 origin, const vec3 dir) {
  44. return traceConeAO(voxels, origin, dir, 0.14 * coneAperture, 2.5 * voxelgiRange);
  45. }
  46. float traceAO(const vec3 origin, const vec3 normal, sampler3D voxels) {
  47. const float angleMix = 0.5f;
  48. const float aperture = 0.55785173935;
  49. vec3 o1 = normalize(tangent(normal));
  50. vec3 o2 = normalize(cross(o1, normal));
  51. vec3 c1 = 0.5f * (o1 + o2);
  52. vec3 c2 = 0.5f * (o1 - o2);
  53. #ifdef HLSL
  54. const float factor = voxelgiOcc * 0.93;
  55. #else
  56. const float factor = voxelgiOcc * 0.90;
  57. #endif
  58. float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE);
  59. col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE);
  60. col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE);
  61. col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE);
  62. col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE);
  63. return (col / 5.0) * factor;
  64. return 0.0;
  65. }
  66. #endif