IntersectClippingPlanes.glsl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // See IntersectionUtils.glsl for the definitions of Ray, Intersections, INF_HIT,
  2. // NO_HIT, setIntersectionPair
  3. /* Clipping plane defines (set in Scene/VoxelRenderResources.js)
  4. #define CLIPPING_PLANES_UNION
  5. #define CLIPPING_PLANES_COUNT
  6. #define CLIPPING_PLANES_INTERSECTION_INDEX
  7. */
  8. uniform sampler2D u_clippingPlanesTexture;
  9. uniform mat4 u_clippingPlanesMatrix;
  10. // Plane is in Hessian Normal Form
  11. vec4 intersectPlane(in Ray ray, in vec4 plane) {
  12. vec3 n = plane.xyz; // normal
  13. float w = plane.w; // -dot(pointOnPlane, normal)
  14. float a = dot(ray.pos, n);
  15. float b = dot(ray.dir, n);
  16. float t = -(w + a) / b;
  17. return vec4(n, t);
  18. }
  19. void intersectClippingPlanes(in Ray ray, inout Intersections ix) {
  20. vec4 backSide = vec4(-ray.dir, -INF_HIT);
  21. vec4 farSide = vec4(ray.dir, +INF_HIT);
  22. RayShapeIntersection clippingVolume;
  23. #if (CLIPPING_PLANES_COUNT == 1)
  24. // Union and intersection are the same when there's one clipping plane, and the code
  25. // is more simplified.
  26. vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, 0, u_clippingPlanesMatrix);
  27. vec4 intersection = intersectPlane(ray, planeUv);
  28. bool reflects = dot(ray.dir, intersection.xyz) < 0.0;
  29. clippingVolume.entry = reflects ? backSide : intersection;
  30. clippingVolume.exit = reflects ? intersection : farSide;
  31. setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX, clippingVolume);
  32. #elif defined(CLIPPING_PLANES_UNION)
  33. vec4 firstTransmission = vec4(ray.dir, +INF_HIT);
  34. vec4 lastReflection = vec4(-ray.dir, -INF_HIT);
  35. for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) {
  36. vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix);
  37. vec4 intersection = intersectPlane(ray, planeUv);
  38. if (dot(ray.dir, planeUv.xyz) > 0.0) {
  39. firstTransmission = intersection.w <= firstTransmission.w ? intersection : firstTransmission;
  40. } else {
  41. lastReflection = intersection.w >= lastReflection.w ? intersection : lastReflection;
  42. }
  43. }
  44. clippingVolume.entry = backSide;
  45. clippingVolume.exit = lastReflection;
  46. setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 0, clippingVolume);
  47. clippingVolume.entry = firstTransmission;
  48. clippingVolume.exit = farSide;
  49. setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX + 1, clippingVolume);
  50. #else // intersection
  51. vec4 lastTransmission = vec4(ray.dir, -INF_HIT);
  52. vec4 firstReflection = vec4(-ray.dir, +INF_HIT);
  53. for (int i = 0; i < CLIPPING_PLANES_COUNT; i++) {
  54. vec4 planeUv = getClippingPlane(u_clippingPlanesTexture, i, u_clippingPlanesMatrix);
  55. vec4 intersection = intersectPlane(ray, planeUv);
  56. if (dot(ray.dir, planeUv.xyz) > 0.0) {
  57. lastTransmission = intersection.w > lastTransmission.w ? intersection : lastTransmission;
  58. } else {
  59. firstReflection = intersection.w < firstReflection.w ? intersection: firstReflection;
  60. }
  61. }
  62. if (lastTransmission.w < firstReflection.w) {
  63. clippingVolume.entry = lastTransmission;
  64. clippingVolume.exit = firstReflection;
  65. } else {
  66. clippingVolume.entry = vec4(-ray.dir, NO_HIT);
  67. clippingVolume.exit = vec4(ray.dir, NO_HIT);
  68. }
  69. setShapeIntersection(ix, CLIPPING_PLANES_INTERSECTION_INDEX, clippingVolume);
  70. #endif
  71. }