Blaze Engine is a real-time, physically-based deferred 3D renderer with the architecture of a game engine. It was written from scratch using C++ and OpenGL. This was my first serious hobby project, created in 2019 with the goal of learning more about physically-based shading, deferred rendering, and game engine architecture.
This project is no longer under active development.
GitHub Repository: https://github.com/b1skit/BlazeEngine
Features:
Blaze Engine supports deferred, High Dynamic Range (HDR) lighting computed with a Cook-Torrance specular BRDF.
-
- At the beginning of each frame, albedo colors, world-space surface normals, RMAO (Roughness, Metallic, Ambient Occlusion) values, emissive colors, world-space positions, depths, and material properties of each visible polygon are rasterized into a set of 32-bit GBuffer render targets.
-
- Lighting is computed by rendering 3D meshes representing the volume encapsulated by each light within the scene.
-
- Forward rendering is also supported as a fallback/debug mode.
The following deferred light types are currently supported:
-
- Directional lights.
-
- Point lights.
-
- Ambient illumination via Image-Based Lighting (IBL).
-
- Light probes are computed from the current HDR skybox texture for both diffuse and specular irradiance contributions.
-
- Ambient illumination via Image-Based Lighting (IBL).
-
- Emissive lighting is evaluated by adding the GBuffer emissive channel on top of the final rendered frame after deferred lighting contributions have been evaluated.
-
- The intensity of emissive contributions is can be tuned via a scaling factor in the config.cfg file.
-
- Brightly illuminated points and large emissive values are used to compute a light bloom post processing effect.
-
- Emissive lighting is evaluated by adding the GBuffer emissive channel on top of the final rendered frame after deferred lighting contributions have been evaluated.
-
- The background of each frame is filled by rendering a spherically-projected HDR skybox texture into each fragment laying on the camera’s far plane.
Shadows are provided for each of Blaze Engine’s deferred lights by rendering 32-bit depth maps from the perspective of each light. Occlusion of each shaded point is determined by testing the depth of each fragment against these depth maps.
-
- Directional light shadows are rendered using an orthogonal camera, into a single 2D depth buffer.
-
- Point light shadows are rendered into the 6 faces of a cube map.
-
- To avoid artifacts common to shadow mapping, the average of a configurable number of samples from the shadow map in the region about the projected fragment position are compared against the fragment depth, with a slope-scaled bias applied.
Post-Processing Effects:
-
- A sigmoid function is used as a high-pass filter to isolate pixels with especially bright illumination after lighting contributions from deferred and emissive lights have been computed. The values are blitted into a half-resolution buffer for efficiency during the remaining post-processing steps.
-
- A simulated HDR light bloom effect is computed by applying multiple passes of a separable, 9-tap Gaussian blur shader to the buffer of high-pass filtered pixel values. The resolution of the frame is halved again during this process for further efficiency during post-processing.
-
- To simulate the light bloom artifacts that occur in real-world cameras, the resulting 1/4 resolution, high-pass filtered, blurred pixel values are added back to the full resolution rendered frame.
-
- Finally, the image is tone-mapped and gamma corrected as it is blitted to the backbuffer for display.
Engine Architecture & Other Details:
-
- First-person fly camera controls: Allows for intuitive scene navigation and camera positioning.
-
- Engine configuration:
-
- A human-editable config.cfg file is used to configure controls, system-specific settings, and rendering parameters.
-
- Command line arguments are used to control common behaviors, such as scene loading.
-
- Engine configuration:
-
- Event System: Engine subsystems can optionally register to receive/handle system events, such as operating system messages, user input, and engine updates.
-
- Log Manager: Message strings can be recorded to the system console, formatted with standard log, warning, or error tags.
Scene, Material, & Texture Support:
-
- Supports loading of .FBX scenes via Assimp (the Open Asset Import Library).
-
- Allows scene geometry, lighting, materials, skyboxes, and cameras to be easily configured via an external commercial 3D package (e.g. Autodesk Maya).
-
- Supports loading of .FBX scenes via Assimp (the Open Asset Import Library).
-
- Supports common texture formats (e.g. .PNG, .JPG, .HDR) via STB ( Sean T. Barrett’s Single-file public domain image libraries for C/C++).
-
- Supports 3-channel RGB Albedo, Normal, and Emissive texture maps.
-
- Supports single-channel Roughness (R), Metallic (M), and Ambient Occlusion (AO) texture maps, via a packed, 3-channel RMAO composite texture for efficiency.
-
- Supports 3-channel, spherically-projected and cube-mapped HDR RGB skybox images.
-
- Used for both rendering a sky texture at the camera’s far plane, and for computing IBL textures used for ambient lighting.
-
- Supports 3-channel, spherically-projected and cube-mapped HDR RGB skybox images.
-
- Supports common texture formats (e.g. .PNG, .JPG, .HDR) via STB ( Sean T. Barrett’s Single-file public domain image libraries for C/C++).
Custom GLSL Shader Pre-Processing & Compositing:
-
- Supports compiler directives such as #include, and #define:
-
- GLSL shaders can be compiled from separate vertex (.vert), geometry (.geom), and gragment (.frag) shader files.
-
- Shaders can #include commonly used boilerplate code, data structures, and utility functions from shared shader source library files (.glsl).
-
- Shader functionality can be enabled/disabled depending on the evaluation of a #define.
-
- Supports compiler directives such as #include, and #define: