IntersectBox.glsl 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // See IntersectionUtils.glsl for the definitions of Ray and NO_HIT
  2. // See convertUvToBox.glsl for the definition of convertShapeUvToUvSpace
  3. /* Box defines (set in Scene/VoxelBoxShape.js)
  4. #define BOX_INTERSECTION_INDEX ### // always 0
  5. */
  6. uniform vec3 u_renderMinBounds;
  7. uniform vec3 u_renderMaxBounds;
  8. struct Box {
  9. vec3 p0;
  10. vec3 p1;
  11. };
  12. Box constructVoxelBox(in ivec4 octreeCoords, in vec3 tileUv)
  13. {
  14. // Find the min/max cornerpoints of the voxel in tile coordinates
  15. vec3 tileOrigin = vec3(octreeCoords.xyz);
  16. vec3 numSamples = vec3(u_dimensions);
  17. vec3 voxelSize = 1.0 / numSamples;
  18. vec3 coordP0 = floor(tileUv * numSamples) * voxelSize + tileOrigin;
  19. vec3 coordP1 = coordP0 + voxelSize;
  20. // Transform to the UV coordinates of the scaled tileset
  21. float tileSize = 1.0 / pow(2.0, float(octreeCoords.w));
  22. vec3 p0 = convertShapeUvToUvSpace(coordP0 * tileSize);
  23. vec3 p1 = convertShapeUvToUvSpace(coordP1 * tileSize);
  24. return Box(p0, p1);
  25. }
  26. vec3 getBoxNormal(in Box box, in Ray ray, in float t)
  27. {
  28. vec3 hitPoint = ray.pos + t * ray.dir;
  29. vec3 lower = step(hitPoint, box.p0);
  30. vec3 upper = step(box.p1, hitPoint);
  31. return normalize(upper - lower);
  32. }
  33. // Find the distances along a ray at which the ray intersects an axis-aligned box
  34. // See https://tavianator.com/2011/ray_box.html
  35. RayShapeIntersection intersectBox(in Ray ray, in Box box)
  36. {
  37. // Consider the box as the intersection of the space between 3 pairs of parallel planes
  38. // Compute the distance along the ray to each plane
  39. vec3 t0 = (box.p0 - ray.pos) * ray.dInv;
  40. vec3 t1 = (box.p1 - ray.pos) * ray.dInv;
  41. // Identify candidate entries/exits based on distance from ray.pos
  42. vec3 entries = min(t0, t1);
  43. vec3 exits = max(t0, t1);
  44. // The actual box intersection points are the furthest entry and the closest exit
  45. float entryT = max(max(entries.x, entries.y), entries.z);
  46. float exitT = min(min(exits.x, exits.y), exits.z);
  47. vec3 entryNormal = getBoxNormal(box, ray, entryT - RAY_SHIFT);
  48. vec3 exitNormal = getBoxNormal(box, ray, exitT + RAY_SHIFT);
  49. if (entryT > exitT) {
  50. entryT = NO_HIT;
  51. exitT = NO_HIT;
  52. }
  53. return RayShapeIntersection(vec4(entryNormal, entryT), vec4(exitNormal, exitT));
  54. }
  55. void intersectShape(in Ray ray, inout Intersections ix)
  56. {
  57. RayShapeIntersection intersection = intersectBox(ray, Box(u_renderMinBounds, u_renderMaxBounds));
  58. setShapeIntersection(ix, BOX_INTERSECTION_INDEX, intersection);
  59. }