用 500 行純 C++ 實現軟體渲染
在本系列文章中,我打算透過從零開始撰寫簡化版克隆,來展示 OpenGL、Vulkan、Metal 與 DirectX 的運作原理。 許多人在學習 3D 圖形 API 的入門關卡時常常卡住。 為了解決這個問題,我準備了一小系列的講座,修完後我的學生就能做出相當實用的渲染器。
任務如下:不使用任何第三方函式庫(尤其是與圖形相關的),我們將產生如下圖所示的影像:

警告:這份教材大致遵循現代 3D 圖形函式庫的結構。 它是一個軟體渲染器。 我無意展示如何撰寫 GPU 應用程式——我想要展示它們是如何運作的。 我堅信理解這些原理對於撰寫高效能的 3D 函式庫應用程式至關重要。
起點
最終的程式碼約有 500 行。 我的學生通常需要 10 到 20 小時的程式設計時間,才能開始做出這樣的渲染器。 輸入是一個由三角網格與紋理組成的 3D 模型。 輸出是一張渲染圖。 程式沒有圖形介面,只會產生一張影像。
為了盡量減少外部依賴,我提供給學生一個單一類別,用來處理 TGA 檔案——這是最簡單的支援 RGB、RGBA 與灰階影像的格式之一。 這將成為我們操作影像的基礎。 一開始,唯一可用的功能(除了載入與儲存影像)就是設定單一像素的顏色。
沒有內建的函式來繪製線段或三角形——我們將全部手動實作。 雖然我提供了我與學生一同撰寫的原始碼,但我並不建議直接使用它,因為親自完成才能真正理解這些概念。 完整的程式碼可在 github 取得,而我提供給學生的初始原始碼可在這裡找到。 以下是起始點:
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.