PBR Renderer

A real time physically based renderer written in C++ with OpenGL.
Overview
This is a simple real time physically based renderer written in C++ with OpenGL. It implements the Cook-Torrance BRDF microfacet model to simulate the reflection of light on a surface.
This project started as a learning exercise and was not intended for production use. The goal was for me to have a project where I could try to design a renderer and its base architecture as well as implement various PBR techniques using OpenGL. It is now a goal to refactor it to make it modular and usable as a library for future graphics projects.
Features
- Cook-Torrance BRDF model
- Material system with texture support
- Forward rendering
- Diffuse and Specular IBL (Image Based Lighting)
- HDRI skyboxes for environment lighting
- Model loading with Assimp
- SSAO (Screen Space Ambient Occlusion)
- HDR Bloom
- Directional light and point lights
- Shadow mapping for both directional and point lights
Technical Details
Rendering Pipeline
The renderer currently uses a forward rendering pipeline. Each object is rendered using its associated material and lighting information in a single pass. While simple, this approach was chosen to keep the architecture understandable during the early stages of the project.
The rendering process includes several stages such as shadow map generation, lighting evaluation, and post-processing effects including SSAO and HDR bloom.
Physically Based Shading
The shading model is based on the Cook-Torrance microfacet BRDF.
Material properties such as albedo, roughness, and metallic are provided through textures, in order to have physically based materials.
Image Based Lighting
The renderer supports image based lighting (IBL) for both diffuse and specular lighting contributions.
Environment lighting is derived from HDR skyboxes. The renderer generates the required precomputed maps, including irradiance maps for diffuse lighting and prefiltered environment maps for specular reflections. A BRDF lookup texture is also used to approximate the specular integration.
This allows objects to receive realistic lighting from the environment even without direct light sources.
Shadows
The renderer supports shadow mapping for both directional lights and point lights.
Directional lights use a standard depth map generated from the light’s perspective. Point lights use a cubemap shadow map to capture depth in all directions around the light source.
These shadow maps are then sampled during the lighting pass to determine shadowed fragments.
Post Processing
Several screen-space effects are implemented:
SSAO (Screen Space Ambient Occlusion) to approximate small-scale occlusion
HDR rendering and bloom to simulate high-intensity light bleeding
These effects are applied as post-processing passes using framebuffers.
Architecture
The project is structured around a small rendering framework responsible for:
-
mesh and model loading using Assimp
-
material management
-
shader abstraction
-
texture and framebuffer management
-
scene rendering
The goal is to progressively refactor the renderer into a more modular architecture where the rendering backend can be reused independently of the application layer.
Future Improvements
The current implementation focuses on experimentation and learning. Several improvements are planned:
-
cleaner separation between renderer and application
-
support for deferred rendering
-
improved shadow techniques such as cascaded shadow maps
-
better resource management and abstraction
-
improved lighting features such as global illumination experiments
Gallery