# A Shader-Based Ray Tracing Engine
## 2 Related Works  
In computer graphics field, interactive realistic graphics results have long been pursued [17; 18]. Ray tracing is one of them, but it has only recently been applied and commercialized due to its immense computing cost in real-time. Since it considers _global illumination_ environment, rather than the traditional _local illumination_ settings, the ray tracing is one of the _global illumination_ and/or _indirect illumination_ methods [6; 19]. It enables the rendering pipeline to achieve more realistic graphics rendering, as shown in Figure 1.  
Ray tracing is actually rendering an image by recursively tracing optical paths from the viewer's eye to virtual light sources _per pixel_[5]. It considers reflection, refraction, and scattering to ultimately compose the luminosity upon the ray's surface contact [20]. From its accelerated implementation point of view, we should consider two different aspects: _global object management_ for the efficient ray-object intersection checks, and _accelerated reflection computing_ at the intersection points. Reflection computing is again macroscopically divided into two parts: _specular_ and _diffuse_. The _specular reflection_ is a regular reflection on a mirror-like surface, and the _diffuse reflection_ is a light scattering occurred on a rough surface, as shown in Figure 2.  
Theoretically, the rays can be traced infinitely, to get the huge number of _reflected bounces_. In contrast, practical implementations limits the reflection computing to get real-time results. The two major factors of the real-time reflection computing is: _ray bouncing count_ and _ray sampling count_. These factors are also related to the final quality of the ray traced rendering images [6; 20]. Specular reflection is highly associated with the _ray bouncing count_, which refers to how much will the single ray bounce between the object surfaces. Likewise, diffuse reflection is associated with the _ray sampling count_ referring to how many rays will be fired on the reflection points. The sampling attribute also affects the _anti-aliasing_ quality of the image, since it is actually one of the super-sampling methods. The ray bouncing is known to be significantly cost-effective than the ray sampling since it occurs seldom in the actual rendering environment; five to six bounces is more than enough in most rendering cases. Ray sampling, on the other hand, is the major reason why ray tracing lacks performance in real-time rendering all the time; due to its nature of _omni-directional_ light scattering, not enough ray sampling will produce disturbingly noisy  
Figure 2: Differences between the specular and diffuse reflections: specuclar reflections occur on mirror-like surfaces, while diffuse reflections shows light scattering effects. illumination as a result. Figure 3 depicts the performance and precision of the implemented diffuse reflection. In our implementation, these _ray bouncing counts_ and _ray sampling counts_ can be controlled to compromise the final image quality and also the processing speed. Another aspect of the ray tracing computation is the global object management. _Ray casting_ is the fundamental steps for performing the _ray-object interactions_. It is actually a procedure of ray collision checking in the virtual space [21,22]. The simplest form of ray casting is to compare all the primitives (or graphics objects) against the ray, taking the time complexity of \(O(n)\) against \(n\) objects in the scene. This _per-ray_ operation therefore ought to get costly as the scene gets populated with more objects, leading the programmers to import the acceleration structure to reduce the cost down to logarithmic as a necessary step [23]. Two major methods lie for the ray casting acceleration structures: _kd-tree_ and _Bounding Volume Hierarchy_ (BVH) [24, 25, 26, 27]. As an example, in Figure 4, a set of triangles labeled with alphabets from \(A\) to \(F\) denotes the primitives in the scene.