用 500 行纯 C++ 实现软件渲染
在本系列文章中,我的目标是通过从头编写一个简化版克隆来展示 OpenGL、Vulkan、Metal 和 DirectX 的工作原理。 许多人在学习 3D 图形 API 的初始障碍上遇到了困难。 为了帮助解决这个问题,我准备了一系列简短的讲座,完成之后我的学生们能够制作出相当有能力的渲染器。
任务如下:在不使用任何第三方库(尤其是与图形相关的库)的情况下,我们将生成如下所示的图像:

警告:这是一个训练材料,松散地遵循现代 3D 图形库的结构。 它是一个软件渲染器。 我并不打算展示如何编写 GPU 应用程序——我想要展示它们是如何工作的。 我坚信,理解这一点对于使用 3D 库编写高效应用程序至关重要。
起点
最终代码大约有 500 行。 我的学生通常需要 10 到 20 小时的编程时间才能开始制作这样的渲染器。 输入是一个由三角化网格和纹理组成的 3D 模型。 输出是一个渲染结果。 没有图形界面,程序只是生成一张图像。
为了尽量减少外部依赖,我为学生提供了一个处理 TGA 文件的类—— 这是支持 RGB、RGBA 和灰度图像的最简单格式之一。 这将作为我们进行图像操作的基础。 在开始时,唯一可用的功能(除了加载和保存图像)是设置单个像素的颜色。
没有用于绘制线段或三角形的内置函数——我们将手动实现所有这些。 虽然我提供了我与学生一起编写的源代码,但我并不推荐直接使用它,因为自己动手做对于理解概念至关重要。 完整代码可在 github 上找到,您可以在这里找到我提供给学生的初始源代码 here。 请看,这就是起点:
main.cpp#include "tgaimage.h"
constexpr TGAColor white = {255, 255, 255, 255}; // attention, BGRA order
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。
预告:使用该渲染器制作的几个示例




0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.