Ghadeer Abou-Saleh | Path Tracing with WebGPU - Attempt #2 [No Audio] @gee8sh | Uploaded 2 years ago | Updated 3 hours ago
For context, please read the description of my first modest attempt at implementing close-to-real-time path tracing (of very simple geometry) with WebGPU. It could be found here: youtu.be/ryyuQ10hblA
This second attempt adds two enhancements that improved a tiny bit the overall animation quality:
- Importance Sampling: this is the process in which the scattered rays are skewed towards light surfaces. This makes the Monte Carlo integration converge faster. However, since there are many light/emissive surfaces in the scene, and to maintain acceptable performance, each surface or tile in the scene would scatter rays towards a maximum of 4 lights per tile. At first these surfaces would scatter rays in all directions (i.e. basic diffuse scattering). But when these rays hit light/emissive surfaces, the originating surface or tile would "remember" that light source, so that following ray samples would be skewed towards that light source. The downside of this approach is that adjacent tiles would randomly favor different light sources, causing artifacts in the form of contrast between these tiles (as can be clearly seen towards the end of the video).
- Denoising: Importance sampling helps reducing noise. But to reduce it even further I applied an "improvised" filter as a post processing step for each frame. It is not exactly a low-pass filter (which would cause lots of blurring). Instead, each pixel is mixed with the "weighted average" of surrounding pixels in a way that is a function of the difference in brightness between the pixel in question and the surrounding ones. If the difference is small, the pixel remains largely intact. If the difference is significant, the surrounding pixels are mixed heavily into the current pixel, almost replacing it. The weighted average of the surrounding pixels is also a function of the geometry. Pixels that are not projected from the same plane as the current pixel are not included in the average. To do that, the filter needs to know the depth, and the normal corresponding to each pixel. This keeps the edges sharp.
Despite all the above, the image quality is still not that good, and noise in them is still significant. But I am happy with the overall result given the modest GPU this runs on (an Nvidia Quadro T1000) and how computationally expensive path tracing is.
The demo: ghadeeras.github.io/pages/path-tracing.html
The source code: github.com/ghadeeras/ghadeeras.github.io/tree/master/src/path-tracing
Cheers!
For context, please read the description of my first modest attempt at implementing close-to-real-time path tracing (of very simple geometry) with WebGPU. It could be found here: youtu.be/ryyuQ10hblA
This second attempt adds two enhancements that improved a tiny bit the overall animation quality:
- Importance Sampling: this is the process in which the scattered rays are skewed towards light surfaces. This makes the Monte Carlo integration converge faster. However, since there are many light/emissive surfaces in the scene, and to maintain acceptable performance, each surface or tile in the scene would scatter rays towards a maximum of 4 lights per tile. At first these surfaces would scatter rays in all directions (i.e. basic diffuse scattering). But when these rays hit light/emissive surfaces, the originating surface or tile would "remember" that light source, so that following ray samples would be skewed towards that light source. The downside of this approach is that adjacent tiles would randomly favor different light sources, causing artifacts in the form of contrast between these tiles (as can be clearly seen towards the end of the video).
- Denoising: Importance sampling helps reducing noise. But to reduce it even further I applied an "improvised" filter as a post processing step for each frame. It is not exactly a low-pass filter (which would cause lots of blurring). Instead, each pixel is mixed with the "weighted average" of surrounding pixels in a way that is a function of the difference in brightness between the pixel in question and the surrounding ones. If the difference is small, the pixel remains largely intact. If the difference is significant, the surrounding pixels are mixed heavily into the current pixel, almost replacing it. The weighted average of the surrounding pixels is also a function of the geometry. Pixels that are not projected from the same plane as the current pixel are not included in the average. To do that, the filter needs to know the depth, and the normal corresponding to each pixel. This keeps the edges sharp.
Despite all the above, the image quality is still not that good, and noise in them is still significant. But I am happy with the overall result given the modest GPU this runs on (an Nvidia Quadro T1000) and how computationally expensive path tracing is.
The demo: ghadeeras.github.io/pages/path-tracing.html
The source code: github.com/ghadeeras/ghadeeras.github.io/tree/master/src/path-tracing
Cheers!