@penguin42 That's what I want to learn.
I'm familiar with the "naive" #RayTracing algorithm, in which you iterate over each pixel on the screen, casting a ray through it and testing for intersections with every object in the scene.
Once you know the intersection, you cast rays towards every light source in the scene, testing for intersections with objects that could occlude the light. Semi-transparent and reflective materials require recursion (with limits).
It's very simple... but too slow.
@penguin42 The schoolbook #RayTracing algorithm has uneven per pixel workload, making parallelization ontothousands of compute units inefficient.
Furthermore, computing the intersections requires access to the entire scene. Efficient data structures tend to be trees of bounding boxes, with recursive lookups.
Some old RT algorithms switched the two nested loops: the outer loop iterates over each triangle in the scene, and the inner one tests for intersections with screen pixels.
The advantage is that you only need to consider the pixels within the projection of the triangle.
You can also completely cull triangles completely occluded by other triangles in front of them.
I don't know whether this improved algorithm is actually a win for scenes with millions of triangles.
Back to the hardware RT: for a long time, GPUs could dispatch the parallel execution of short functions (historically called shaders). Each instance gets constants such as texture data and variables such as transformed coordinates. The output of these functions can be used to paint pixels on the screen or intermediate buffers.
With this, we reached the boundaries of my hands-on knowledge of #GPU accelerated rendering.
This is a little program I wrote a few years ago to learn the basics of GLSL shaders:
https://github.com/codewiz/mandelwow
(it's also the very first code I wrote in #Rust, please forgive the poor style).
The first step to understanding real-time #RayTracing involves a leap to #Vulkan, which generalizes the old #OpenGL rendering model to enable building parallel, multi-pass pipelines using low-level primitives such as command buffers, queues, etc.
I've been reading a few introductory guides, and this is the official one:
https://github.com/KhronosGroup/Vulkan-Guide
Enter the #Vulkan #RayTracing spec, which was finalized over 2 years ago.
Like OpenGL, Vulkan evolves by means of vendor extensions which get then standardized and, later, incorporated into the core API.
https://www.khronos.org/blog/vulkan-ray-tracing-final-specification-release
The vendor-neutral ray tracing acceleration emerges from the composition of several building blocks, such as VK_KHR_ray_query:
https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_ray_query.html
You can guess from the number of contributors that standardization took considerable effort. The API must support a variety of use-cases, including hybrid rendering.
Ray queries are the simplest of two available techniques, in which SPIRV shaders can cast arbitrary rays and get back a (distance sorted?) list of hits.
The more advanced technique is used in the screenshot at the beginning of this thread: Ray Tracing Pipelines.
This extension is present in #Mesa, but still flag-guarded for the RADV driver. It crashed my RDNA3 card until last week
AFAICT, the #Vulkan RT pipeline takes away control of the core algorithm, calling shaders attached to surfaces in the scene when they're hit.
This diagram shows that ray generation is still performed by a user-defined shader: