A real-time physically-based render engine built with Metal and Swift.
- OBJ Loader - Import 3D models in OBJ format
- Instanced Rendering - Efficient GPU-driven instance rendering
- Dual Shading Models
- Blinn-Phong shading for traditional lighting
- Physically-Based Rendering (PBR) with metallic-roughness workflow
- Shadow Mapping - Point light omnidirectional shadows using cube map arrays with PCF filtering
- Scene Graph - N-ary tree structure for hierarchical transforms
- Scene Persistence - Save and load scenes to/from disk in JSON format
- Asset Management - Centralized asset loading and caching
- ImGui Integration - Interactive editor layer for scene manipulation
- Real-time Controls - Adjust materials, lights, and transforms in real-time
The PBR implementation follows industry-standard techniques for realistic material rendering:
Uses the Disney Diffuse Model from Burley 2012:
- More physically accurate than Lambertian diffuse
Implements the Cook-Torrance microfacet model (Cook & Torrance 1982):
- Normal Distribution Function (NDF): GGX/Trowbridge-Reitz for realistic highlights
- Geometry Function: Smith's separable masking-shadowing function
- Fresnel: Schlick approximation for angle-dependent reflectance
Environment-based lighting using prefiltered cube map arrays:
- Split-sum approximation following Epic's 2013 approach
- Prefiltered environment maps - Multiple roughness levels stored in cube texture arrays
- BRDF Integration LUT - Precomputed environment BRDF for real-time performance
- Diffuse and Specular IBL - Separate contributions for accurate material response
Point lights use omnidirectional shadow mapping:
- Cube map array storage (one cube per light)
- Percentage-Closer Filtering (PCF) for soft shadow edges
- Poisson disk sampling for better quality
- Distance-based depth testing in world space
Scenes are serialized to JSON with a hierarchical structure:
{
"rootNode": {
"assetId": "root",
"id": "E746668A-A378-4042-833C-FDF1852C7747",
"nodeType": -1,
"transform": {
"position": [0, 0, 0],
"scale": [1, 1, 1]
},
"children": [
{
"id": "A5069381-FEAF-4191-B1B6-9069FDD2CE4B",
"assetId": "e3dd97f8f84d2a54a95aac60bde6e2274cf39fe3073c15fd8c309dc1aa73d978",
"nodeType": 0,
"transform": {
"position": [-0.8385614, 1.1081522, -2.5150156],
"scale": [1, 1, 1]
},
"children": []
}
]
}
}Each node includes:
- Unique identifier (UUID)
- Asset reference (SHA-256 hash)
- Transform data (position, rotation, scale)
- Children array for hierarchy
- Metal - Apple's low-level graphics API
- MetalKit - Texture loading and view management
- Metal Performance Shaders - GPU-accelerated image processing
- Forward rendering pipeline - Single-pass rendering with multiple materials
- Cube texture arrays - Efficient storage for environment maps and shadow maps
- GPU-driven rendering - Minimize CPU overhead with instancing
- Open the
.xcodeprojfile in Xcode - Build and run (⌘R)
Requires:
- Xcode 14.0+
- macOS 12.0+ deployment target
- Metal-capable Mac