Graphics Renderer using Vulkan

 

Introduction

This renderer is a course project for the CMU-15672 Real-Time Graphics class. It is a graphics renderer that will render a scene with animations using the Vulkan API. This renderer is written in C++ 17. 


The renderer supports basic mesh rendering, Instanced Rendering, Camera Movement, Frustum Culling, Off-Screen Rendering, Environment CubeMap, Normal Mapping, Parallax Occlusion Mapping, and Material with different pipelines. More detail will be shown below and in the Github Repo/Submissions.


The renderer is still under development, and will support more features like lightings and shadow maps.

PROJECT source code

About this Project

Input Source

The input of this renderer will be a special file type called S72; it is a JSON-like scene graph that can be generated from a Blender project.  

I've implemented a JSON Parser, called "XZJParser", that can parse the S72 file and load it as a scene graph. 

Instanced Rendering

To better optimize the performance, I've implemented the instanced rendering that can draw all the instances of a mesh in one draw call. The implementation uses a instance buffer to store all the instances' model matrix. And I bind it to the vertex attributes as a per-instance data. I've tested the performance using RenderDoc.

Render without instanced rendering. (Avg. 0.44FPS and 100000 draw calls per frame)

Render with instanced rendering. (Avg. 27FPS and 8 draw calls per frame)

Frustum Culling

I've also implemented the frustum culling using the SAT (Separating Axis Theorem). 

User-Camera View: 

The objects that are actually rendered:

Environment & Materials

The renderer can read a RGBE environment cube map (Converted from a HDR image), which can be used for the materials. 


The renderer supports five types of materials: Simple Color, Environment, Mirror, Lambertian (Diffused BRDF), and PBR (Principled BRDF). 


To letmaterials work in real time, the renderer will use a pre-compute lambertian&environment look-up tables. The idea is referenced from Real Shading in Unreal Engine 4. The repository has a utility called "Cubes" which can convert a RGBE environment cube map to those look-up tables. Its implementation uses a Monte-Carlo Estimation with Uniform Sampling and GGX Importance Sampling. 


Each material type has its own Vulkan render pipeline and descriptor sets. Since the renderer also supports multiple materials with the same material types, each material also has its own descriptor sets. For each material type, it also has its own vertex shader and fragment shader that are written in GLSL.