用500行纯C++实现软件渲染
摘要
一个教程系列,通过用500行C++从零构建软件渲染器(无需外部库),演示OpenGL、Vulkan、Metal和DirectX的工作原理。
暂无内容
查看缓存全文
缓存时间: 2026/07/24 05:00
# 主页 - 用代码玩耍
来源:https://haqr.eu/tinyrenderer/
## 500行纯C++实现的软件渲染器
在这个系列文章中,我旨在通过从零编写一个简化版的着色器,展示OpenGL、Vulkan、Metal和DirectX的工作原理。令人惊讶的是,许多人在学习3D图形API的第一步就遇到了困难。为了帮助解决这个问题,我准备了一系列简短的讲座,经过这些讲座后,我的学生已经能够制作出功能相当强大的渲染器。
任务如下:不使用任何第三方库(特别是图形相关的库),我们将生成一张类似这样的图片:
*警告:这是一份教学材料,大致遵循现代3D图形库的结构。这是一个**软件渲染器**。**我无意展示如何编写GPU应用程序——我想展示它们是如何工作的。**我坚信理解这一点对于编写使用3D库的高效应用程序至关重要。*
## 起点
最终代码大约有500行。我的学生通常需要10到20小时的编程时间才能开始制作这样的渲染器。输入是一个由三角形网格和纹理构成的3D模型。输出是一张渲染图像。没有图形界面,程序只是生成一张图片。
为了尽量减少外部依赖,我给我的学生提供了一个用于处理TGA (http://en.wikipedia.org/wiki/Truevision_TGA)文件的类——这是支持RGB、RGBA和灰度图像的最简单格式之一。这是我们图像处理的基础。一开始,唯一可用的功能(除了加载和保存图像)就是设置单个像素的颜色。
没有内置的函数用于绘制线段或三角形——我们将手动实现所有这些功能。虽然我提供了自己的源代码(与我的学生一起编写),但我不建议直接使用它,因为自己做这些工作对于理解概念至关重要。完整代码可在github (https://github.com/ssloy/tinyrenderer)上找到,而我提供给学生的初始源代码可以在这里 (https://github.com/ssloy/tinyrenderer/tree/706b2dfecff65daeb93de568ee2c2bd87f277860)找到。看,这是起点:
main.cpp``
#include "tgaimage.h"
constexpr TGAColor white = {255, 255, 255, 255}; // 注意,BGRA顺序
constexpr TGAColor green = { 0, 255, 0, 255};
constexpr TGAColor red = { 0, 0, 255, 255};
constexpr TGAColor blue = {255, 128, 64, 255};
constexpr TGAColor yellow = { 0, 200, 255, 255};
int main(int argc, char** argv) {
constexpr int width = 64;
constexpr int height = 64;
TGAImage framebuffer(width, height, TGAImage::RGB);
int ax = 7, ay = 3;
int bx = 12, by = 37;
int cx = 62, cy = 53;
framebuffer.set(ax, ay, white);
framebuffer.set(bx, by, white);
framebuffer.set(cx, cy, white);
framebuffer.write_tga_file("framebuffer.tga");
return 0;
}
``
它生成了64x64的图像`framebuffer.tga`,这里我为了更好的可读性将其放大:
## 编译
``
git clone https://github.com/ssloy/tinyrenderer.git &&
cd tinyrenderer &&
cmake -Bbuild &&
cmake --build build -j &&
build/tinyrenderer obj/diablo3_pose/diablo3_pose.obj obj/floor.obj
``
渲染后的图像保存在`framebuffer.tga`中。## 预告:使用该渲染器制作的一些示例
---
相似文章
用500行纯C++实现软件渲染
本教程系列教你如何用500行C++从头编写一个软件渲染器,并解释现代3D图形API的内部工作原理。
周末掌握3D Gaussian Splatting
一篇使用C++和OpenGL从零构建简化版3D Gaussian Splatting渲染器的教程,涵盖加载和渲染Gaussian splats。
编写一个无绑定GPU抽象层
一位开发者分享了他们实现的无绑定GPU抽象层Loon GPU,它基于Vulkan 1.3和Metal 4,灵感来自Sebastian Aaltonen的《No Graphics API》博客文章。该库使用GPU指针、顶点拉取和无绑定纹理堆来简化现代图形API。
我为 Emacs 构建了一个 GPU 后端
作者描述了如何在 macOS 上使用 Metal、在 Linux 上使用 OpenGL 为 Emacs 构建基于 GPU 的显示后端,从而提升渲染性能并启用视频播放和动画光标等新效果,且无需修改核心重新显示引擎。
Show HN: 从零编写C++光线追踪器,无AI依赖
一位开发者从零构建了Luz,这是一个零依赖的C++20路径追踪器,具备蒙特卡洛路径追踪、全局光照、BVH加速以及Blender到Luz导出器功能。