"What I cannot create, I do not understand."
这是一个从零开始编写的软件光栅化渲染器,不依赖任何图形 API (OpenGL/DirectX/Vulkan)。项目旨在通过纯 CPU 计算模拟完整的 3D 渲染管线,深入探究图形学的底层数学原理与工程实现。
不仅复现了经典的渲染算法,还集成了一个完全交互式的 GUI 环境,支持实时调整光照、切换渲染模式及各种调试功能。
测试模型:African Head (约 15,000 三角面) | 分辨率:800x600 | 平台:Windows 10
- CPU: [Intel Core i7-12700H] @ 2.30GHz (Single Core / Multi-thread)
- RAM: 32 GB DDR4
- Optimization: OpenMP Enabled (Parallel Rasterization)
| Render Mode | FPS (Avg) | Frame Time | Computational Cost |
|---|---|---|---|
| Wireframe | 60+ FPS | < 16.6 ms | Low (Vertex Processing Only) |
| Blinn-Phong | ~25 FPS | ~40.0 ms | High (Per-pixel Lighting + Texture) |
| 4x MSAA | ~15 FPS | ~66.6 ms | Very High (4x Depth Samples) |
为了在 CPU 上实现可交互的帧率,项目实施了以下优化:
-
Back-face Culling (背面剔除):
- 在光栅化阶段前计算三角形法线,剔除背向摄像机的面。
- 收益: 减少了约 50% 的像素着色计算量。
-
Bounding Box Traversal (包围盒遍历):
- 仅遍历三角形 AABB (Axis-Aligned Bounding Box) 内的像素,而非全屏扫描。
-
收益: 将像素遍历复杂度从屏幕分辨率
$O(W \times H)$ 降低至三角形大小相关。
-
Parallel Rasterization (OpenMP):
- 利用
#pragma omp parallel for对三角形光栅化循环进行多线程加速。 - 收益: 在多核 CPU 上提升了约 40%-60% 的渲染性能。
- 利用
-
Early-Z Test (早期深度测试):
- 在执行复杂的 Fragment Shader (纹理采样/光照计算) 之前,先进行深度测试。
- 收益: 避免了被遮挡像素的无效计算。
集成了 Dear ImGui,允许在运行时实时调整 Shader 参数、观察模型细节并监控性能。
支持多种渲染模式的实时热切换,用于调试几何结构与光照计算。
| FogEffect | Wireframe Mode | Blinn-Phong Shading |
![]() |
![]() |
![]() |
| 基于距离的雾颜色和物体颜色的插值运算 (带背面剔除) |
基于重心坐标的三角形光栅化 (带背面剔除) |
基于法线插值的高光渲染 (带纹理映射) |
- Math Library: 手写数学库,实现了
Vector,Matrix,Quaternion等核心运算。 - Transform: 完整的 MVP (Model-View-Projection) 变换矩阵推导。
- Clipping: 视锥体裁剪 (Frustum Culling) 与 齐次空间裁剪。
- Rasterization:
- 基于包围盒 (Bounding Box) 的三角形遍历算法。
- 透视校正插值 (Perspective Correct Interpolation):修复纹理在透视投影下的扭曲。
- 深度测试 (Z-Buffering):处理复杂的物体遮挡关系。
- 可编程管线模拟: 抽象了
VertexShader和FragmentShader,模拟 GPU 工作流。 - 光照模型:
- Flat Shading
- Gouraud Shading
- Phong & Blinn-Phong Shading
- 纹理映射: 支持 Diffuse Map(漫反射贴图)与 Specular Map(高光贴图),使用双线性插值采样。
- 高级特性:
- Gamma Correction: 线性空间光照计算。
- Linear Fog: 基于深度的线性雾效。
- Interactive UI: 集成 ImGui,支持 FPS 统计、参数滑块调节。
- Camera System: 实现了类似 FPS 游戏的摄像机控制(平移/旋转/缩放)。
- Debug Tools: 世界空间网格 (Grid)、坐标轴可视化、线框模式切换。
- Performance: 使用 OpenMP 进行多线程像素着色加速。
| 操作 | 功能 | 描述 |
|---|---|---|
| Left Drag (左键拖拽) | 旋转视角 | 围绕中心点进行轨道旋转 (Orbit) |
| Right Drag (右键拖拽) | 平移相机 | 在屏幕空间平移视口 (Pan) |
| Scroll (滚轮) | 缩放 | 推拉相机距离 (Zoom) |
| 按键 | 功能 | 说明 |
|---|---|---|
| Ctrl + Z | 切换渲染模式 | 在 Wireframe / Flat / Blinn-Phong 间循环 |
| Shift + 1/2/3 | 切换模型 | 加载并切换场景中的不同模型 |
| P | 投影模式切换 | 切换透视投影 (Perspective) / 正交投影 (Orthographic) |
| G | 网格显示 | 开启/关闭地面辅助网格 |
| Ctrl + G | 简单网格 | 切换网格的精细度模式 |
| U | 雾效开关 | 开启/关闭线性深度雾 (Linear Fog) |
| Q | Gamma 校正 | 开启/关闭 SRGB Gamma 校正 |
| ESC | 退出程序 | 关闭查看器 |
| 按键 | 功能 |
|---|---|
| T | 推进时间 |
| R | 自动旋转 |
| 按键 (Numpad) | 功能 | 按键组合 | 功能 |
|---|---|---|---|
| Numpad . | 聚焦模型 (Focus) | F | 恢复默认视角 (Reset) |
| Numpad 1 | 前视图 (Front) | Ctrl + 1 | 后视图 (Back) |
| Numpad 3 | 右视图 (Right) | Ctrl + 3 | 左视图 (Left) |
| Numpad 7 | 顶视图 (Top) | Ctrl + 7 | 底视图 (Bottom) |
- Compiler: C++17 (MSVC / GCC / Clang)
- Dependencies: SDL2 (Window & Input)
# 1. Clone the repository
git clone [https://github.com/Klia145/YuuTinyRender.git](https://github.com/Klia145/YuuTinyRender.git)
cd YuuTinyRender# 2. Build
mkdir build && cd build
cmake ..
cmake --build . --config Release# 3. Run
# Windows (PowerShell)
.\bin\viewer.exe
# Linux / macOS
./bin/viewer
#or
./build_cmake.ps1 特别感谢以下优秀的教程与课程,为本项目提供了理论基础与灵感:
- TinyRenderer - Dmitry V. Sokolov
- 本项目的核心灵感来源。跟随教程理解了光栅化的从零实现过程。
- GAMES101: 现代计算机图形学入门 - 闫令琪 (Lingqi Yan)
- 提供了坚实的图形学数学基础(线性代数、变换、透视矫正)与理论支持。
- LearnOpenGL - Joey de Vries
- 在实现 Blinn-Phong 光照模型、伽马校正及纹理系统时提供了宝贵的参考。
本项目站在巨人的肩膀上,使用了以下开源库来处理窗口与交互:
- SDL2: 用于跨平台的窗口管理与输入事件处理。
- Dear ImGui: 用于构建实时的交互式调试界面。
- stb_image: 用于加载和解析纹理图片。






