I implemented this renderer during Fall Break in 2023, with my strong interest to immigrate more algorithm in GPU.
Here are some results I achieved. Everything is rendered in real-time. Here are some results.
My renderer currently supports SAH BVH construction on CPU and visualization (as the grey boxes you can see) . It also supports reading unity legacy materials and transfer them into Raytracing property. The algorithm using compute shader to run ray tracing method on GPU.
I majorly take this reference from David Kuri. I implemented my own way building BVH and raytracing on GPU.
Render Pipeline. The graph show how do compute
The graph below shows how do we collect data from each objects and store it into corresponding GPU Buffers.
Another key data structure is the BVH. Each node stores the left&right leaf or the triangles it contains.
It is hot topic about how could we best split each BVH node so to have a good balance and simplicity. A good BVH node should best describe how the information inside is locates. And SAH (Surface Area Heuristic) is a good approach to achieve this point. The principle of this algorithm is to avoid overlapping of each bounding box.
The higher SAH value we get, the more efficient for each ray to hit object. So to find the best SAH split points, I actually run all the possible slice points on each axis and get the highest value. I sliced the volume into 10 sub-volume. and compare each value to find the best.
since the number of triangles in each BVH leaf is uncertain, some may have 2 or 3 some may even have 100 + (when the depth is higher than 60). So when the BVH node reference the triangles, I store the starting offset in trianglesBuffer and the counts of triangles. This method not only make triangles trackable but also increase the data continuity on buffer.
if the node is not leaf node, then the “offset” and “length” is corresponding map to the “left” and “right” nodes index.
as for how triangles are linking to geometry data, there is the graph. The triangle, which stores the corresponding Object ID, Material ID and three vertices info.
Hit with BVHnode is done by “AABB intersect”, here is the code. The idea is very simple, we check the period hit into3 axis. if these period exist overlapping between each of axis, which means hit, if not then miss.
tmin = (bot.x - r.origin.x) * r.invDir.x;
tmax = (top.x - r.origin.x) * r.invDir.x;
if (tmin > tmax) { // swap
tmp = tmin; tmin = tmax; tmax = tmp;
}
tymin = (bot.y - r.origin.y) * r.invDir.y;
tymax = (top.y - r.origin.y) * r.invDir.y;
if (tymin > tymax) { // swap
tmp = tymin; tymin = tymax; tymax = tmp;
}
if ((tmin > tymax) || (tymin > tmax)) // miss
return false;
tmin = max(tmin, tymin);
tmax = min(tmax, tymax);
tzmin = (bot.z - r.origin.z) * r.invDir.z;
tzmax = (top.z - r.origin.z) * r.invDir.z;
if (tzmin > tzmax) { // swap
tmp = tzmin; tzmin = tzmax; tzmax = tmp;
}
if ((tmin > tzmax) || (tzmin > tmax)) // miss
return false;
tmin = max(tmin, tzmin);
tmax = min(tmax, tzmax);
t = float2(tmin, tmax);
return true;
I use the Aronberg method to fast calculate the triangle hit. You can find it in this paper.