MongooseVK
A Vulkan-based Real-Time Renderer
Introduction
This project is a deep dive into the Vulkan graphics API, aimed at building a real-time 3D renderer from the ground up. Written in C++, the renderer serves as both a learning platform and a foundation for future projects. The primary goal is to gain hands-on experience with Vulkan's explicit and low-level design while developing a modular rendering system that can later be reused as a standalone library.
Project structure
The renderer is structured into two main components:
Engine Library: A statically linked C++ library that encapsulates all Vulkan-related functionality. This includes rendering abstractions, resource management, and core engine systems. Designed with reusability in mind, this library is intended to serve as the foundation for future applications or integrations.
Demo Application: A standalone executable that links against the engine library. It provides a sandbox environment for testing and visualizing engine features in real time.
The project uses CMake as its build system, handling project generation, dependency management, and configuration across multiple platforms and build types. This ensures consistent builds and streamlined integration of external libraries.

Rendering pipeline
The renderer implements a physically based rendering (PBR) pipeline using the metallic-roughness workflow. This approach aims to produce realistic materials and lighting by simulating how light interacts with surfaces based on physical properties.
Key components of the pipeline include:
Lighting: A single directional light is currently supported, complete with shadow mapping to provide dynamic shadows and depth perception in the scene.
Image-Based Lighting (IBL): A high dynamic range (HDR) image is used as the source for both the environment cubemap and static reflections. This same HDR data is processed for diffuse and specular IBL, enhancing material realism through indirect lighting.
Skybox: The scene’s background is rendered using a cubemap, derived from the HDR environment, giving a sense of immersion and realistic ambient contribution.

Resources
Scene Importing: To enable working with larger scenes without the need for an in-engine editor, the renderer loads complete scene data—meshes, materials, and textures—directly from a GLTF file. This approach allows complex environments to be brought into the renderer quickly and consistently using a standardized format.
Lighting & Environment: While most scene data comes from the GLTF file, lights (currently a directional light) and the skybox are added programmatically. This allows for flexible control over lighting setups and environmental configuration.
Shaders: All shaders are authored in GLSL (OpenGL Shading Language). At runtime, these shaders are compiled into SPIR-V—Vulkan’s native shader format—when a scene is loaded. The system currently supports vertex and fragment shaders, with plans to extend support to additional shader stages in the future.

User Interface
The renderer integrates ImGui, a popular immediate-mode GUI library for C++, to provide a lightweight and responsive user interface layer.
The UI serves several key purposes:
Parameter Control: Real-time adjustment of rendering parameters.
Visualization: On-screen display of internal engine data such as frame timings, camera parameters, light directions, etc.
Debug Views: The UI also enables visualizing various internal textures (e.g., shadow maps, G-buffer) to aid in debugging and development.

Feature Highlights
Screen Space Ambient Occlusion (SSAO): A simple yet effective implementation of SSAO adds subtle shadowing in creases and contact areas, improving depth perception and surface detail without the need for global illumination.
Cascaded Shadow Maps (CSM): For the directional light, cascaded shadow mapping is used to maintain high-resolution shadows across a wide view frustum. This ensures better shadow quality in both near and distant scene regions.
Infinite Ground Grid: A dynamic, camera-aligned ground grid helps ground the scene visually and provides a spatial reference—especially useful for previewing assets in large or open environments.


Challenges
Developing a renderer with Vulkan poses a unique set of challenges due to its explicit, low-level nature. This project has been a hands-on exploration of several core areas:
Understanding Vulkan's Architecture: A major early challenge was simply learning how Vulkan is structured—its separation of concerns, synchronization model, and the many stages involved in creating and managing GPU resources. Gaining a clear mental model of Vulkan's building blocks was essential before writing any meaningful code.
Abstraction Layer / API Wrapping: To manage Vulkan's verbosity and complexity, a custom wrapper layer was implemented around the core API.
Resource & Memory Management: Instead of relying on RAII and (smart) pointers, the renderer uses object memory pools and handle-based access for managing Vulkan resources. This approach helps with memory efficiency, lifetime tracking, and avoids common pitfalls with dangling references or ownership ambiguity.
Bindless Textures: To simplify texture usage and reduce descriptor set complexity, the renderer supports bindless textures. This allows shaders to access a large number of textures through an index, enabling more flexible material systems.
Material Pooling: Material parameters are stored in a large, contiguous pool, and shaders reference them by index. This enables efficient GPU access and helps avoid redundant state changes or material duplication.
Planned Features
Several key improvements and architectural enhancements are planned to evolve the renderer into a more powerful and reusable system:
Frame Graph System: A frame graph will be introduced to manage render passes, resource lifetimes, and image layout transitions automatically.
This will help reduce boilerplate code and provide better control over render passes.
Multi-threading: Improve load times and better hardware utilization.
Library: The engine is being refactored to become a modular, reusable library, separating core functionality from the demo application. This will allow future projects to integrate the renderer as a plug-and-play component.
Advanced Rendering Features: Many features from a prior OpenGL renderer are planned for implementation in Vulkan, including:
- Support for additional light source types (point, spot)
- Shadow map atlas for managing multiple dynamic shadows efficiently
- Dynamic sky system with atmospheric scattering
- Range of post-processing effects (bloom, tone mapping, exposure control, etc.)