Implemented a CPU-based software rasterizer that simulates how OpenGL works without using any third-party libraries but using gabime/spdlog for logging though :)
# Clone
git clone https://github.com/forkercat/ForkerRenderer.git
cd ForkerRenderer
# Compile
mkdir build && cd build
cmake .. && make
# Usage: <scene filename>
./ForkerRenderer ../scenes/test.scene
- Physically-Based Rendering (PBR)
- Improvement
- Global Illuminations
- Screen Space Reflection (SSR) aka. Realtime Ray Tracing
- Rasterization
- Bresenham's Line Algorithm (used and removed)
- Bounding Box Method (currently used)
- Rendering Methods
- Forward Rendering
- Deferred Rendering
- G-Buffers: depth, world position, normal, albedo, etc
- Geometry Pass
- Lighting Pass
- Shading
- Depth Shading
- Geometry Shading (for deferred rendering)
- Blinn-Phong Shading
- PBR Material and Shading
- Cook-Torrance reflectance equation
- D: Trowbridge-Reitz GGX
- F: Fresnel-Schlick approximation
- G: Smith's method with Schlick-GGX
- Parsing
*.obj
/*.mtl
g
defines mesh name;usemtl
defines m_Material name (comes in order)- Support
Ka
,Kd
,Ks
,Ke
,map_Kd
,map_Ks
,map_Ke
,map_Bump
,map_Ao
,map_Pr
,map_Pm
- Position vertex normalization
- Auto triangulation
- Parsing scene files
*.scene
# Test Scene
screen 1280 800
# forward/deferred rendering
mode deferred
ssaa off 2
shadow on
# Light (type: point/dir, position, color)
light point 2 5 5 1 1 1
# Camera (type: persp/ortho, position, lookAt)
camera persp -1 1 1 0 0 -1
# Models (filepath, position, rotate_y, uniform scale)
model obj/plane/plane.obj false false 0 -1 -1 0 3
# Mary
model obj/mary/mary.obj true true 0.05 0 -1 -10 1
- Geometry Template Class
- Vector:
Vector2f
,Vector3f
,Vector4f
,Vector4i
, ... - Matrix:
Matrix3f
,Matrix4f
,Matrix3x4f
, ... - Support glm-style vector swizzling, e.g.
v.xyz
,v.xy
- Vector:
- Light: Point / Directional
- AreaLight is defined by
AREA_LIGHT_SIZE
in shadow mapping)
- AreaLight is defined by
- Texture Mapping:
- Diffuse / Specular / Normal / Emissive
- Roughness / Metalness / Ambient Occlusion
- Texture Wrapping: NoWrap / ClampToEdge / Repeat / MirroredRepeat
Texture::WrapMode
- Texture Filtering: Nearest / Linear (Bilinear)
Texture::FilterMode
- Normal Transformation: TBN Matrix
- Generate and average m_Tangents for each vertex when loading the model
- Camera: Orthographic / Perspective Projection
- Perspective Correct Interpolation (PCI)
#define PERSPECTIVE_CORRECT_INTERPOLATION
- Shadow Effect
- Hard Shadow: Shadow Mapping (set
shadow on
intest.scene
and comment out below macros) - Soft Shadow:
- Percentage-Closer Filtering (PCF)
#define SOFT_SHADOW_PCF
- Percentage-Closer Soft Shadow (PCSS)
#define SOFT_SHADOW_PCSS
- Percentage-Closer Filtering (PCF)
- Hard Shadow: Shadow Mapping (set
#ifdef SOFT_SHADOW_PCF
// Percentage-Closer Filtering (PCF)
visibility = PCF(uShadowBuffer, shadowCoord, bias, PCF_FILTER_SIZE);
#elif defined(SOFT_SHADOW_PCSS)
// Percentage-Closer Soft Shadow (PCSS)
visibility = PCSS(uShadowBuffer, shadowCoord, bias);
#else
// Hard Shadow
visibility = HardShadow(uShadowBuffer, shadowCoord, bias);
#endif
- Anti-Aliasing (AA)
- SSAA: Super-Sampling Anti-Aliasing (set
ssaa on
intest.scene
) - MSAA: Multi-Sample Anti-Aliasing
- SSAA: Super-Sampling Anti-Aliasing (set
- Global Illuminations
- Screen Space Ambient Occlusion (SSAO)
ssao on
- Range Check (courtesy of John Chapman)
- Noise Reduction: simple 9x9 blur, two-pass Gaussian blur
- Screen Space Reflection (SSR)
- Aka. Screen Space Ray Tracing
- Screen Space Ambient Occlusion (SSAO)
Apex Horizon (also Dr. Mary Somers) [Squral]
Mary [TAs from GAMES202: Real-time High Quality Rendering]
Horizon Meets Mary
Sci-Fi Welding Vehicle [Berk Gedik]
Cafe Menu Chalkboard [Naiyararahman]
Gossblade Greatsword (Monster Hunter Rise) [taj_tajima]
Backpack [Berk Gedik]
African Head [Vidar Rapp]
About 5,500 lines of code:
- Rendering:
render.h/cpp
(rendering functions),forkergl.h/cpp
(rasterization) - Buffer:
buffer.h/cpp
(Buffer1f
,Buffer3f
) - Shader:
shader.h
,phongshader.h
,pbrshader.h
,depthshader.h
,gshader.h
- Shadow:
shadow.h/cpp
- Scene:
scene.h/cpp
,scenes/test.scene
- Model:
model.h/cpp
,mesh.h/cpp
,material.h
,pbrmaterial.h
,texture.h
- Camera:
camera.h/cpp
- Light:
light.h
- Color:
color.h
- Geometry:
geometry.h/cpp
- Utility:
tgaimage.h/cpp
,output.h/cpp
,check.h
,utility.h
,constant.h
,stringprint.h
(PBRT-v3)
$ ./ForkerRenderer scenes/test.scene
[info] Scene File: 'scenes/test.scene'
[info] [Mode] Forward Rendering
[info] [Screen] 1280 x 800
[info] [Point Light] position: [ 2.00000000, 5.00000000, 5.00000000 ], color: [ 1.00000000, 1.00000000, 1.00000000 ]
[info] [Camera] position: [ -1.00000000, 1.00000000, 1.00000000 ], lookAt: [ 0.00000000, 0.00000000, -1.00000000 ]
[info] [Model] 'obj/diablo_pose/diablo_pose.obj'
[info] v# 2519, f# 5022, vt# 3263, vn# 2519, tg# 2519, mesh# 1, mtl# 1 | normalized[o] generateTangent[o], flipTexCoordY[o]
[info] [Diablo_Pose] f# 5022 | PBR[x] map_Kd[o] map_Ks[o] map_Ke[x] map_Bump[o] | Ka(0.10, 0.10, 0.10), Kd(0.81, 0.81, 0.81), Ks(0.20, 0.20, 0.20)
[info] [Config] SSAA(x2)[off] shadow[on] SSAO[off]
[info] ------------------------------------------------------------
[info] Time Used: 0.714729 Seconds (Scene Loaded)
[info] Shadow Pass:
[info] [Status] Enabled
[info] [Diablo_Pose] Time Used: 0.106988 Seconds
[info] ------------------------------------------------------------
[info] Time Used: 0.858756 Seconds (Shadow Pass)
[info] Forward Pass (Blinn-Phong):
[info] [Diablo_Pose] Time Used: 3.92819 Seconds
[info] ------------------------------------------------------------
[info] Time Used: 3.97755 Seconds (Forward Pass)
[info] Anti-Aliasing (SSAA):
[info] [Status] Disabled
[info] ------------------------------------------------------------
[info] Time Used: 4.87400e-06 Seconds (Anti-Aliasing)
[info] Output TGA File: 'output/framebuffer.tga'
[info] Output TGA File: 'output/shadowmap.tga'
[info] Output TGA File: 'output/zbuffer.tga'
Started by following the basic workflow in ssloy/TinyRenderer, improved code style (e.g. geometry.h
) when referring
to other great resources such as mmp/pbrt-v3 & v4, and resolved tons of issues with the help of the Internet. Thank those authors and creators who wrote the articles and built the models!
Rendering:
- ssloy/TinyRenderer
- mmp/pbrt-v3 & v4
- lingqi/GAMES101
- lingqi/GAMES202
- Scratchapixel
- JoeyDeVries/LearnOpenGL
- OpenGL Projection Matrix
- The Normal Matrix
- Perspectively Correct Texture Mapping And color Interpolation
- Converting quadrilaterals in an OBJ file into triangles?
- OBJ FILE FORMAT
- Object Files (.obj)
- More and more articles...
Model Credits:
- Apex Horizon by Squral
- Sci-Fi Welding Vehicle by Berk Gedik
- Backpack by Berk Gedik
- African Head by Vidar Rapp
- Diablo Pose by Samuel (arshlevon) Sharit
- Mary by TAs in GAMES202: Real-time High Quality Rendering
- Cafe Menu Chalkboard by Naiyararahman
- Gossblade Greatsword by taj_tajima
- Brickwall, Plane, Catbox (for debugging) by MYSELF! :)