Skip to content

Instantly share code, notes, and snippets.

@DomNomNom
Last active May 22, 2024 02:59
Show Gist options
  • Save DomNomNom/46bb1ce47f68d255fd5d to your computer and use it in GitHub Desktop.
Save DomNomNom/46bb1ce47f68d255fd5d to your computer and use it in GitHub Desktop.
Ray-AABB (Axis Aligned Bounding Box) intersection.
// adapted from intersectCube in https://github.com/evanw/webgl-path-tracing/blob/master/webgl-path-tracing.js
// compute the near and far intersections of the cube (stored in the x and y components) using the slab method
// no intersection means vec.x > vec.y (really tNear > tFar)
vec2 intersectAABB(vec3 rayOrigin, vec3 rayDir, vec3 boxMin, vec3 boxMax) {
vec3 tMin = (boxMin - rayOrigin) / rayDir;
vec3 tMax = (boxMax - rayOrigin) / rayDir;
vec3 t1 = min(tMin, tMax);
vec3 t2 = max(tMin, tMax);
float tNear = max(max(t1.x, t1.y), t1.z);
float tFar = min(min(t2.x, t2.y), t2.z);
return vec2(tNear, tFar);
};
@TheAIBot
Copy link

TheAIBot commented Jul 25, 2023

Leaving this here if anyone needed this for C# with 3 dimensional vectors.
SIMD optimized implementation that returns true if an intersection was found.

public bool Intersects(Ray ray)
{
    Vector4 tMin = (MinPosition - ray.Origin) / ray.Direction;
    Vector4 tMax = (MaxPosition - ray.Origin) / ray.Direction;
    Vector128<float> t1 = Vector4.Min(tMin, tMax).AsVector128();
    Vector128<float> t2 = Vector4.Max(tMin, tMax).AsVector128();

    Vector128<float> tNear = Sse.Max(Sse.Max(Sse.MoveHighToLow(t1, t1),
                                             Sse.Shuffle(t1, t1, 0b00_00_11_01)),
                                     t1);

    Vector128<float> tFar = Sse.Min(Sse.Min(Sse.MoveHighToLow(t2, t2),
                                            Sse.Shuffle(t2, t2, 0b00_00_11_01)),
                                    t2);

    return tNear.GetElement(0) <= tFar.GetElement(0) && tFar.GetElement(0) >= 0;
}

Obviously if you need an optimal solution for a single ray to check many boxes then get rid of the division operators.

public bool Intersects(RayAxisAlignBoxOptimizedIntersection optimizedRay)
{
    Vector4 tMin = (MinPosition - optimizedRay.Start) * optimizedRay.InverseDirection;
    Vector4 tMax = (MaxPosition - optimizedRay.Start) * optimizedRay.InverseDirection;

@Codezigineer
Copy link

That type name is absurdly long.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment