Moments in Graphics
A blog by Christoph Peters

My toy renderer: Overview

Published 2021-06-24, updated 2022-06-01

Update 2022-06-01: Added the post on animations.

Alongside my latest papers I released the underlying renderer as open source. It is a real-time deferred renderer with ray traced shadows based on Vulkan and written in C. As I wrote it, I had the liberty to try some unconventional designs and techniques. So I did, because that is an excellent way to learn new things. It also became the basis for our work on vertex-blend attribute compression.

Most of these things worked out nicely. I'm writing this blog post series in hopes that others may learn from it as well. And maybe some others want to toy with this code base. Here is an overview of all posts in the series:

Part 1: Keep it simple
This post laments long compile times, explains why I chose C over other programming languages, some fundamental design choices and how the renderer interacts with Vulkan.
Part 2: Scene management
Here I explain how I get scenes from Blender onto the GPU while keeping load times short.
Part 3: Rendering basics
The renderer uses a visibility buffer [Burns2013], the Frostbite BRDF for all surfaces [Lagarde2015], Monte Carlo integration with stratified random numbers [Ahmed2020] and linearly transformed cosines [Heitz2016]. This post motivates these choices and highlights some interesting aspects of my implementation.
Part 4: Ray tracing
Ultimately, the purpose of this whole project is to demonstrate importance sampling strategies for polygonal and linear lights. This post describes these techniques and alternative approaches.
Part 5: Animations
More recently, I repurposed the renderer to compare different techniques for compression of vertex-blend attributes. This post explains how I support animations in the model file format and use them in the renderer.

The series is not supposed to be a complete documentation of the renderer but it should make it easier to familiarize yourself with the code base. The code has plenty of comments and I did my best to keep it as clear as possible, especially for those familiar with Vulkan and GLSL. It also has very few dependencies, making it easy to compile and to play with it. If you do, you can get some neat renderings such as Figure 1.

Figure 1: An attic from BlendSwap (CC-BY) rendered with ray traced shadows at two samples per pixel using my importance sampling for polygonal lights. This frame renders in 1.5 ms on an RTX 2080 Ti at 1440².



Ahmed, Abdalla G. M. and Wonka, Peter (2020). Screen-Space Blue-Noise Diffusion of Monte Carlo Sampling Error via Hierarchical Ordering of Pixels. ACM Transactions on Graphics (proc. SIGGRAPH Asia), 39(6). Official version | Author's version

Burns, Christopher A. and Hunt, Warren A. (2013). The Visibility Buffer: A Cache-Friendly Approach to Deferred Shading. Journal of Computer Graphics Techniques, 2(2):55-69. Official version

Heitz, Eric and Dupuy, Jonathan and Hill, Stephen and Neubelt, David (2016). Real-time Polygonal-light Shading with Linearly Transformed Cosines. ACM Transactions on Graphics (proc. SIGGRAPH), 35(4). Official version | Author's version

Lagarde, Sébastian and de Rousiers, Charles (2015). Physically Based Shading in Theory and Practice: Moving Frostbite to PBR. ACM SIGGRAPH 2014 Courses, article 23. Author's version