C++17 voxel-based rendering engine for Windows featuring a modular, interchangeable backend architecture supporting Vulkan 1.4 (Dynamic Rendering) and OpenGL 4.6 Core.
- Physically-inspired Water Rendering
- Post-Processing Fog
- Screen-Space Ambient Occlusion (SSAO)
- Fast Approximate Anti-Aliasing (FXAA)
- Camera View Frustum Culling
- Greedy Meshing for Chunks
- Memory-Efficient Vertex Storage
- Procedural terrain generation using LibNoise
- Block placement and destruction
- World data persistence:
- Auto-saving world state
- Manual save system
- WASD – Move
- Mouse – Free-look camera (when in camera mode)
- Left Click – Break block
- Right Click – Place block
Note: The application starts in camera control mode by default.
=— Enable camera control mode- Allows free-look camera movement (mouse + keyboard).
-— Enable cursor mode- Releases the mouse cursor for interacting with the ImGui control panel.
Left Arrow— Hide ImGui panelsRight Arrow— Show ImGui panels
Multi-frame-in-flight architecture with per-frame resources (descriptor sets, UBOs) to avoid CPU-GPU synchronization hazards.
This project focuses on implementing real-time rendering techniques that are commonly used in modern game engines. Each technique was implemented from scratch with explicit control over GPU resources and pipeline state.
Note: FPS comparisons were recorded at the same camera position. Relative gains are hardware-agnostic; absolute FPS varies by GPU.
Vulkan backend utilizes dynamic rendering (no render passes/framebuffers) for flexible multi-pass composition.
- G-buffer pass (normals + depth)
- SSAO pass + blur
- Water reflection & refraction passes
- Forward render (scene objects)
- Post-Processing Fog
- FXAA
- UI Elements
- Water is rendered using a dedicated pass that captures the scene above and below the water plane into reflection and refraction textures.
- Utilizes Fresnel-based reflection/refraction blending.
- DuDv mapping for wave distortion effects coupled with time-based animation.
- Refraction depth texture used to make shallow water appear lighter in color.
Why it matters:
Previous versions of this engine showcased flat and boring water blocks. Water is now more visually appealing and takes into account other objects in the scene.
- Screen-space, depth-based fog applied as a post-processing pass.
- Configurable fog color and start/end distances.
- Integrates seamlessly with SSAO, FXAA, and lighting passes.
Why it matters:
Demonstrates the ability to implement additional post-processing effects that integrate cleanly into an existing post-processing pipeline.
- Utilizes a G-buffer that stores view space normals and depth.
- Generates a random sample kernel in view space and projects samples into screen space.
- Calculates occlusion by comparing sampled depth values against the current fragment depth.
- A blur pass is applied to reduce high frequency noise while preserving edge detail.
Why it matters:
SSAO adds depth perception and contact shadows without the cost of full global illumination, significantly improving visual realism in dense voxel environments.
- Implements FXAA 3.11 by Timothy Lottes
(based on https://gist.github.com/kosua20/0c506b81b3812ac900048059d2383126) - A post-processing pass that operates on the final scene color buffer.
- Identifies and smooths jagged edges.
Why it matters:
FXAA is a cost-efficient method for anti-aliasing with minimal performance cost that is ideal for voxel engines.
- Each chunk is tested against the camera's view frustum using Axis-Aligned Bounding Box (AABB) vs frustum plane checks.
- Only the chunks visible from inside the frustum are rendered.
- Integrated directly into the chunk manager (CPU side) to avoid extra GPU load through draw calls.
- Noticeable performance increase from 679 FPS to 1057 FPS (~56% improvement) measured on an RTX 5090 at the same camera position.
Why it matters:
Frustum culling drastically reduces GPU workload by efficiently rendering only the chunks visible in camera view, reducing overhead and increasing performance as the world grows in size.
- The chunk mesh is generated using greedy meshing, which scans each chunk in three passes (one per axis).
- For each pass, adjacent voxels are compared to detect visible faces. Adjacent faces that match in attributes are merged into larger quads.
| GPU | Optimizations Off (FPS) | Optimizations On (FPS) | FPS Change | % Increase |
|---|---|---|---|---|
| Intel Arc A370M | 39.9 | 73.8 | +33.9 | +85.0% |
| AMD Radeon 780M | 39.3 | 90.7 | +51.4 | +130.8% |
| Nvidia RTX 4060m | 103.0 | 210.1 | +107.1 | +104.0% |
| Nvidia RTX 5090 | 342.2 | 662.0 | +319.8 | +93.5% |
Why it matters:
Greedy meshing reduces the number of draw calls and triangles sent to the GPU, improving overall rendering performance.
- Significantly reduced the per-vertex memory footprint for opaque geometry.
- Previously, each vertex stored position (vec3), normal (vec3), and UV (vec2) totaling 32 bytes. The optimized format packs this data into a single uint32_t (4 bytes).
- ~88% reduction in RAM usage: 1579 MB -> 185 MB.
- ~14% reduction in VRAM usage: 5282 MB -> 4526 MB.
Note: VRAM reduction is smaller than RAM reduction due to textures and framebuffers dominating total GPU memory usage.
Why it matters:
Smaller vertices reduce CPU memory pressure, improve cache efficiency, and allow significantly larger worlds and higher chunk counts without exhausting system memory.
- Utilizes the LibNoise library to generate a terrain heightmap.
- This allows for varied terrain features such as hills, oceans, and trees.
Why it matters:
Procedural generation allows for large, varied worlds without having to worry about doing so by hand, while maintaining a deterministic state.
- Chunk data is serialized to disk using a custom save format.
- Supports both manual and automatic saving.
- As the player modifies (place/destroy blocks) the world, these changes persist through application shutdown and restart.
Why it matters:
Persistent world state demonstrates data-oriented design beyond real-time rendering.
| Terrain Generation + Skybox |
|---|
| Initial terrain generation using a simple heightmap. |
![]() |
| Terrain Generation w/LibNoise |
|---|
| Terrain generation using LibNoise for more interesting views, trees are WIP. |
![]() |
| Proper Tree Generation |
|---|
| Updated tree generation to randomly construct canopy. |
![]() |
| G-buffer Normal | G-buffer Depth |
|---|---|
| Working on implementing SSAO. Implemented G-buffer with debug view for surface normals. | Working on implementing SSAO. Implemented G-buffer with debug view for depth. |
![]() |
![]() |
| Frustum Culling (Off) | Frustum Culling (On) |
|---|---|
| FPS: 679 | FPS: 1057 = ~56% Increase in performance |
![]() |
![]() |
![]() |
![]() |
| Flat Water | Beautiful Water |
|---|---|
| Previous version of engine using static water textures. | Enhanced water using reflection/refraction textures, and DuDv distortion. |
![]() |
![]() |
| Fog (Off) | Fog (On) |
|---|---|
| World rendered without fog enabled. | Post-processing fog used to obscure objects further away. |
![]() |
![]() |
| OpenGL Render | Vulkan Render |
|---|---|
| Scene rendered in OpenGL. | Scene rendered in Vulkan. |
![]() |
![]() |
- Clone repo:
git clone https://github.com/RobRob7/ProjectAtlas.git
- Then run commands:
cd ProjectAtlas
mkdir build
cd build
cmake ..
cmake --build . --config Release
- For Command Prompt:
cd Release
Atlas.exe
- For Git Bash:
cd Release
./Atlas.exe
Libraries already provided, the following are used:
| Library | Usage | Version |
|---|---|---|
| Glad | OpenGL loader generator | N/A |
| GLFW | API for creating windows, contexts and surfaces, receiving input and events | v3.4 |
| GLM | Header only C++ mathematics library | v1.01 |
| ImGui | Bloat-free Graphical User interface for C++ | v1.92.5 |
| LibNoise | A portable, open-source, coherent noise-generating library for C++ | v1.0.0 |
Project layout:
- include/
- internal header files
- src/
- main.cpp → main driver
- chunk/
- opengl/
- chunk_mesh_gpu_gl.cpp → chunk mesh opengl
- vulkan/
- chunk_mesh_gpu_vk.cpp → chunk mesh vulkan
- chunk_data.cpp → chunk data
- chunk_manager.cpp → management of chunk meshes
- chunk_mesh.cpp → chunk mesh
- opengl/
- core/
- application.cpp → main application
- scene.cpp → object setup + renderer call opengl
- scene_vk.cpp → object setup + renderer call vulkan
- light/
- light.cpp → light cube object opengl
- light_vk.cpp → light cube object vulkan
- main_opengl/
- opengl_main.cpp → opengl main instance
- main_vulkan/
- buffer_vk.cpp → buffer helper class
- descriptor_set_vk.cpp → descriptor set helper class
- graphics_pipeline_vk.cpp → pipeline helper class
- vulkan_main.cpp → vulkan main instance
- player/
- crosshair.cpp → crosshair UI icon opengl
- crosshair_vk.cpp → crosshair UI icon vulkan
- renderer/
- opengl/
- chunk_pass_gl.cpp → opaque chunk render
- debug_pass.cpp → G-buffer normal + depth view
- fog_pass.cpp → fog pass
- fxaa_pass.cpp → FXAA pass
- gbuffer_pass.cpp → G-buffer pass
- present_pass.cpp → final image pass
- renderer_gl.cpp → render pipeline
- ssao_pass.cpp → SSAO pass
- water_pass.cpp → water pass
- vulkan/
- chunk_pass_vk.cpp → opaque chunk render
- debug_pass_vk.cpp → G-buffer normal + depth view
- fog_pass_vk.cpp → fog pass
- fxaa_pass_vk.cpp → FXAA pass
- gbuffer_pass_vk.cpp → G-buffer pass
- present_pass_vk.cpp → final image pass
- renderer_vk.cpp → render pipeline
- ssao_pass_vk.cpp → SSAO pass
- water_pass_vk.cpp → water pass
- opengl/
- save/
- save.cpp → world state saving
- system/
- camera.cpp → camera system
- ui/
- ui.cpp → UI system opengl
- ui_vk.cpp → UI system vulkan
- utility/
- opengl/
- cubemap_gl.cpp → setup + render cubemap
- shader.cpp → shader helper class
- texture.cpp → setup texture
- ubo_gl.cpp → UBO upload
- vulkan/
- cubemap_vk.cpp → setup + render cubemap
- image_vk.cpp → texture base
- shader_vk.cpp → shader helper
- texture_2d_vk.cpp → load texture from file
- texture_cubemap_vk.cpp → load multiple textures from file
- utils_vk.cpp → transition image helpers
- opengl/
- res/
- shader/ → Shaders
- texture/ → Textures
- deps/ → Dependency files
- papers/ → Papers implemented




























