Skip to content

Commit

Permalink
Implementation of raytracing in implicitBVH.jl
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack-Grogan committed Nov 4, 2024
1 parent 9434775 commit bbcce31
Show file tree
Hide file tree
Showing 11 changed files with 575 additions and 542 deletions.
49 changes: 48 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ detection downwards from this level.

## Examples

### Multithreaded Contact Detection

Simple usage with bounding spheres and default 64-bit types:

```julia
Expand Down Expand Up @@ -127,7 +129,7 @@ traversal = traverse(
Check out the `benchmark` folder for an example traversing an STL model.


# GPU Bounding Volume Hierarchy Building and Traversal
### GPU-Accelerated Contact Detection

Simply use a GPU array for the bounding volumes; the interface remains the same, and all operations - Morton encoding, sorting, BVH building and traversal for contact finding - will run on the right backend:

Expand Down Expand Up @@ -155,6 +157,51 @@ traversal = traverse(bvh)
```


### Multithreaded Ray Tracing

Using `BSphere{Float32}` for leaves, `BBox{Float32}` for merged nodes above, and `UInt32` Morton codes:

```julia
using ImplicitBVH
using ImplicitBVH: BBox, BSphere

# Load mesh and compute bounding spheres for each triangle. Can download mesh from:
# https://github.com/alecjacobson/common-3d-test-models/blob/master/data/xyzrgb_dragon.obj
using MeshIO
using FileIO

mesh = load("xyzrgb_dragon.obj")

# Generate bounding spheres around each triangle in the mesh
bounding_spheres = [BSphere{Float32}(tri) for tri in mesh]

# Build BVH
bvh = BVH(bounding_spheres, BBox{Float32}, UInt32)

# Generate some rays
points = rand(Float32, 3, 1000)
directions = rand(Float32, 3, 1000)

# Traverse BVH to get indices of rays intersecting the bounding spheres
traversal = traverse_rays(bvh, points, directions)
@show traversal.contacts

# output
traversal.contacts = Tuple{Int32, Int32}[...]
```

The bounding spheres around each triangle can be computed in parallel (including on GPUs) using [AcceleratedKernels.jl](https://github.com/anicusan/AcceleratedKernels.jl):

```julia
import AcceleratedKernels as AK

bounding_spheres = Vector{BSphere{Float32}}(undef, length(mesh))
AK.map!(BSphere{Float32}, bounding_spheres, mesh)
```

For GPUs simply swap `Vector` with `ROCVector`, `MtlVector`, `oneVector` or `CuVector`, and AcceleratedKernels will automatically run the code on the right GPU backend (from `AMDGPU`, `Metal`, `oneAPI`, `CUDA`).


# Implicit Bounding Volume Hierarchy

The main idea behind the ImplicitBVH is the use of an implicit perfect binary tree constructed from some
Expand Down
1 change: 1 addition & 0 deletions docs/src/bounding_volumes.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ ImplicitBVH.BSphere

```@docs
ImplicitBVH.iscontact
ImplicitBVH.isintersection
ImplicitBVH.center
```

Expand Down
3 changes: 0 additions & 3 deletions prototype/raytracing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ for (ibv, iray) in bvt.contacts
end


# TODO Brute force tests for comparison
# TODO document rays and integrate them in bounding_volumes.jl
# TODO add example to README
# TODO include in docs/
# TODO maybe a pretty image / render?
# TODO benchmark against a standard raytracer? Check Chitalu's paper; the Stanford bunny example

3 changes: 1 addition & 2 deletions src/ImplicitBVH.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ using GPUArraysCore: AbstractGPUVector, @allowscalar
import AcceleratedKernels as AK


# Include code from other files
include("utils.jl")
include("morton.jl")
include("implicit_tree.jl")
include("bounding_volumes.jl")
include("bounding_volumes/bounding_volumes.jl")
include("build.jl")
include("traverse/traverse.jl")
include("raytrace/raytrace.jl")
Expand Down
Loading

0 comments on commit bbcce31

Please sign in to comment.