Rookie Awards 2024 - Open for Entries!
3D real-time Vulkan renderer from scratch
Share  

3D real-time Vulkan renderer from scratch

Seppe Dekeyser
by seppedekeyser on 31 May 2022 for Rookie Awards 2022

My Vulkan renderer that I built from scratch in C++ as a learning exercise. Although it initially started as a project to practice my skills, it grew into something bigger and in my opinion worth showing off.

6 771 0
Round of applause for our sponsors

This is a Vulkan renderer I wrote from scratch in C++. I started the project back in 2020, after I finished a tutorial on Vulkan. At the time I understood how the main concepts of the API work, but couldn't quite wrap my head around how to use it in a more complex project, which is why I started this project.

In the end, I ended up going on a long and deep dive into more of the details of the Vulkan API and how to write a game engine of sorts. I absolutely loved working on this project, and loved learning a lot from all the little challenges that stood in my way.
Below the overview video I go into more details on some of the technical aspects of the project.

Shader hot-reloading

This was a fun little side-quest to figure out, because going into this I had no clue where to start. In the end I realized that all I had to do was simply destroy the current render pass and graphics pipeline, reload the shader files and recreate the render pass and graphics pipeline.

Because of my small abstraction layer, this was fairly easy to implement, and the end code resulted in something like this:

Pipeline builder

A major pain point I identified was setting up pipelines in Vulkan. They require a lot of boilerplate structs to be filled out with the necessary information. To make this easier, I made a PipelineBuilder helper class. With simply calling a few functions, these structs get filled and the pipeline gets created. Another benefit I found was that I could simply re-use the builder, change some properties and create a different unique pipeline without too much extra code.

This is roughly how to use this PipelineBuilder:

Simple texture manager

I ended up writing a small asset manager, but in its current implementation it only manages textures. The main reason behind this is that I didn't want to have to load the same texture multiple times. This was especially important to me when I worked on model loading, and needed a fallback default texture if a material didn't have a specific texture.

Internally, the asset manager simply holds a map of strings and asset references. An asset reference is nothing more than a pointer to the asset, and a count to how many references there are still alive.

When we request a texture through the asset manager, it first checks if it has already loaded that one before. If it has, it increases the refCount for that asset and returns the asset. Otherwise, it will load in the texture on-the-fly, store it to keep track of it and then return it.

Upon releasing a texture, it first checks if there are other references currently alive. Only when you release the last instance of that asset, does the asset effectively get destroyed.

ECS scene system

I really wanted to implement an ECS in this project, because I had not implemented one before. I chose EnTT to do the heavy-lifting, after hearing quite a few other people recommend it after they implemented it in their own projects and games.

In its current implementation, my scene system is just a thin wrapper around EnTT to make it play nicely in my project.

Although this was useful to do through code, I could see this becoming quite annoying to work with over time, which is why I added a serialization/deserialization system that can save and load these scenes from and to a JSON file.

The models in the demo video were downloaded from Morgan McGuire's Computer Graphics Archive https://casual-effects.com/data

- Crytek Sponza - © 2010 Frank Meinl, Crytek - provided under the CC BY-NC license
- Amazon Lumberyard Bistro - © 2017 Amazon Lumberyard - provided under the CC-BY 4.0 license


Comments (0)

This project doesn't have any comments yet.