ObbIntersection.azsl 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/Features/RayTracing/RayTracingIntersectionAttributes.azsli>
  9. #include <Atom/Features/SrgSemantics.azsli>
  10. // https://github.com/erich666/GraphicsGems/blob/master/gems/RayBox.c
  11. bool IntersectRayAABB(float3 rayOrigin, float3 rayDirection, float3 aabbMin, float3 aabbMax, out float t, out float3 normal, out float2 uv)
  12. {
  13. t = 0.f;
  14. normal = float3(1, 0, 0);
  15. float3 maxT;
  16. for (int i = 0; i < 3; i++)
  17. {
  18. if ((rayOrigin[i] < aabbMin[i] || rayOrigin[i] > aabbMax[i]) && rayDirection[i] != 0)
  19. {
  20. maxT[i] = ((rayOrigin[i] < aabbMin[i] ? aabbMin[i] : aabbMax[i]) - rayOrigin[i]) / rayDirection[i];
  21. }
  22. else
  23. {
  24. maxT[i] = -1;
  25. }
  26. }
  27. int whichPlane = 0;
  28. for (int i = 1; i < 3; i++)
  29. {
  30. if (maxT[whichPlane] < maxT[i])
  31. {
  32. whichPlane = i;
  33. }
  34. }
  35. t = maxT[whichPlane];
  36. if (t < 0)
  37. {
  38. return false;
  39. }
  40. int uvAxis = 0;
  41. for (int i = 0; i < 3; i++)
  42. {
  43. if (whichPlane != i)
  44. {
  45. float coord = rayOrigin[i] + t * rayDirection[i];
  46. if (coord < aabbMin[i] || coord > aabbMax[i])
  47. {
  48. return false;
  49. }
  50. uv[uvAxis++] = (coord - aabbMin[i]) / (aabbMax[i] - aabbMin[i]);
  51. }
  52. }
  53. normal = float3(0, 0, 0);
  54. normal[whichPlane] = rayDirection[whichPlane] > 0 ? -1 : 1;
  55. return true;
  56. }
  57. [shader("intersection")]
  58. void ObbIntersection()
  59. {
  60. const float3 aabbMin = float3(-1, -1, -1);
  61. const float3 aabbMax = float3(1, 1, 1);
  62. float t;
  63. float3 normal;
  64. float2 uv;
  65. if (IntersectRayAABB(ObjectRayOrigin(), ObjectRayDirection(), aabbMin, aabbMax, t, normal, uv))
  66. {
  67. ProceduralGeometryIntersectionAttributes attrib;
  68. attrib.SetPosition(ObjectRayOrigin() + ObjectRayDirection() * t);
  69. attrib.SetNormal(normal);
  70. attrib.SetUv(uv);
  71. attrib.SetTangent(float4(1, 0, 0, 1));
  72. ReportHit(t, 0, attrib);
  73. }
  74. }