推薦直接閱讀博客原文外构,更新更及時(shí)方椎,閱讀體驗(yàn)更佳
如果你覺(jué)得我寫的不錯(cuò)筷笨,就給我個(gè)點(diǎn)個(gè)贊吧??!謝謝你吉嚣,這對(duì)我真的很重要!
「十天自制軟渲染器」這個(gè)標(biāo)題我承認(rèn)標(biāo)題黨了.在對(duì)圖形學(xué)一無(wú)所知的情況下想十天自制一個(gè)軟渲染器蹬铺,就好似一節(jié)課沒(méi)上過(guò)卻試圖一個(gè)晚上看完《30 天精通 C++》然后第二天早上八點(diǎn)考試得滿分一樣尝哆,我承認(rèn)世界上有這種天才,但很可惜我不是甜攀。
就像前文所說(shuō)秋泄,本系列造的輪子都是站在巨人的肩膀上完成的,需要對(duì)相關(guān)知識(shí)有一定的了解和學(xué)習(xí)规阀,如果你是一個(gè)圖形學(xué)大牛恒序,這種軟渲染器肯定是不屑于做的;如果你剛剛進(jìn)入圖形學(xué)的大門谁撼,造一個(gè)軟渲染器的輪子歧胁,非常利于你鞏固自己的底層知識(shí)。
<br />
本文主要(90%)參考 ssloy 大神的 tinyrenderer 教程,零依賴實(shí)現(xiàn)一個(gè)軟渲染器喊巍,通過(guò)這個(gè)教程可以實(shí)現(xiàn)一個(gè)簡(jiǎn)易版本的 OpenGL2.0
(即 rendering pipeline 只支持 Vertex Shader
和 Fragment Shader
兩種自定義 Shader 類型)屠缭,了解 OpenGL
這類圖形學(xué) API 在底層是如何工作的。
我自己造的輪子是 toyRenderer崭参,在 tinyrenderer 的基礎(chǔ)上加入了大量的注釋并按自己的理解優(yōu)化了部分代碼(不排除有反向優(yōu)化)呵曹,如果大家對(duì) tinyrenderer 感興趣,可以參考一下我的實(shí)現(xiàn)和我現(xiàn)在寫的這個(gè)教程何暮,點(diǎn)個(gè) star ?? 就更好不過(guò)了~
本專欄的目錄結(jié)構(gòu)和 tinyrenderer 保持一致奄喂,方便大家對(duì)比閱讀。
<br />
前置知識(shí)
要想看懂 tinyrenderer 的代碼郭卫,需要有一定的知識(shí)儲(chǔ)備砍聊,下面是我在造輪子時(shí)的一些總結(jié),大家學(xué)習(xí)前可以參考一下贰军。
1.數(shù)學(xué)
對(duì)于圖形學(xué)來(lái)說(shuō)玻蝌,數(shù)學(xué)是一道繞不過(guò)的坎兒;對(duì)于這個(gè)軟渲染器器輪子來(lái)說(shuō)词疼,并沒(méi)有涉及太多的數(shù)學(xué)內(nèi)容俯树,我個(gè)人總結(jié)如下:
1.1 高中數(shù)學(xué)
造一個(gè)軟渲染器需要你還記得一些高中幾何的內(nèi)容,難度都不大贰盗,比如說(shuō)直線的坐標(biāo)公式许饿,重心坐標(biāo)等。
1.2 微積分
微積分其實(shí)只有少量的涉及舵盈,原教程里有一點(diǎn)點(diǎn)梯度的內(nèi)容陋率,個(gè)人感覺(jué)對(duì)整體學(xué)習(xí)進(jìn)度影響不大。
1.3 線性代數(shù)
線性代數(shù)涉及的內(nèi)容比較多秽晚,從最簡(jiǎn)單的向量瓦糟,再到各種坐標(biāo)系變換,都需要對(duì)線性代數(shù)有比較扎實(shí)的理解赴蝇。
如果你線性代數(shù)都忘的差不多了菩浙,這里我推薦 3Blue1Brown 的教程——《線性代數(shù)的本質(zhì)》,這是我見(jiàn)過(guò)最好的線性代數(shù)入門教程了句伶。而且圖形學(xué)里涉及的矩陣變換絕大部分都是三維空間的劲蜻,基本上看完這門課就可以上手圖形學(xué)的學(xué)習(xí)了。
<br />
2.圖形學(xué)
圖形學(xué)入門課程我只推薦一個(gè)考余,閆令琪大神的《GAMES101-現(xiàn)代計(jì)算機(jī)圖形學(xué)入門》先嬉。
閆令琪大神有多厲害我就不多介紹了,最關(guān)鍵的是 GAMES101 優(yōu)點(diǎn)太多了:
- 全中文講解秃殉,大大降低國(guó)內(nèi)小伙伴的學(xué)習(xí)門檻
- 課程非常新坝初,2020 年初才開課浸剩,不會(huì)存在課程/教案過(guò)時(shí)的情況
- 知識(shí)點(diǎn)全面钾军,正如課程名「現(xiàn)代圖形學(xué)入門」鳄袍,本課程不但講了經(jīng)典的光柵化成像,還講了光線追蹤等相對(duì)較新較前沿的內(nèi)容
學(xué)完這門課可以收獲什么呢吏恭?比如說(shuō) 2077 的圖形設(shè)置面板你都知道是啥意思了
如果跟著這門課學(xué)下來(lái)拗小,其實(shí)課下作業(yè)就會(huì)完成一個(gè)小的軟渲染器,但由于我是后期才加入學(xué)習(xí)的樱哼,所以作業(yè)也沒(méi)有跟著做哀九,經(jīng)過(guò)搜索發(fā)現(xiàn) tinyrenderer 這個(gè)教程推薦的人最多,所以最后參照這個(gè)教程實(shí)現(xiàn)了自己的軟渲染器搅幅。
閆老師的是視頻教程阅束,大家可以配合他的 PPT 學(xué)習(xí)。如果習(xí)慣看書茄唐,我這里推薦兩本息裸,一本是大名鼎鼎的虎書《Fundamentals of Computer Graphics 4th Edition》,另一本是《Real Time Rendering 4th》沪编,都是非常經(jīng)典非常有名的書籍呼盆。
這兩本書國(guó)內(nèi)都沒(méi)有引進(jìn),我這里有英文版的 PDF蚁廓,大家可以看我個(gè)人簡(jiǎn)介访圃,關(guān)注「鹵蛋實(shí)驗(yàn)室」后回復(fù)「圖形學(xué)」獲取下載鏈接。
<br />
3.C++
本渲染器是用 C++ 寫的相嵌,但用到的都是基礎(chǔ)語(yǔ)法腿时,稍微高級(jí)點(diǎn)兒的知識(shí)就是模版編程和操作符重載。個(gè)人認(rèn)為只要有其他語(yǔ)言基礎(chǔ)饭宾,看個(gè)半小時(shí)的 C++ 語(yǔ)法就可以上手實(shí)踐了批糟。
<br />
如果上面的三個(gè)知識(shí)點(diǎn)都掌握的差不多了,我打保票十天內(nèi)肯定能寫出一個(gè)軟渲染器捏雌;如果沒(méi)有掌握好(尤其是圖形學(xué)基礎(chǔ)知識(shí))跃赚,十天內(nèi)實(shí)現(xiàn)是有些夠嗆。廢話不多說(shuō)性湿,我們先去搭環(huán)境吧纬傲!
本教程要做的是一個(gè)零依賴的軟渲染器,所以依賴的環(huán)境就是 C++
的開發(fā)環(huán)境肤频。
注:零依賴意味著這個(gè)項(xiàng)目不依賴任何第三方庫(kù)叹括,軟渲染意味著所有計(jì)算都是在 CPU 側(cè)進(jìn)行的,沒(méi)有 GPU 參與
C++
環(huán)境搭建配置有多種方法宵荒,最快捷的方式就是直接用高度集成的 IDE汁雷,win 電腦可以用 Visual Studio净嘀,Mac 用戶可以用 Xcode。當(dāng)然你也可以用 CMake + VSCode 搭建 C++
運(yùn)行環(huán)境侠讯。
我這個(gè)人很懶挖藏,平常開發(fā) Xcode 用的又比較多,不想多折騰了厢漩,所以直接用 Xcode 構(gòu)建項(xiàng)目了膜眠,小伙伴們千萬(wàn)不要學(xué)習(xí)我這種壞習(xí)慣。
Xcode 創(chuàng)建 C++
項(xiàng)目
1.新建項(xiàng)目
1.Xcode 創(chuàng)建 C++
項(xiàng)目非常簡(jiǎn)單溜嗜,啟動(dòng) XCode 后點(diǎn)擊 Create a new Xcode project
宵膨,創(chuàng)建一個(gè)新項(xiàng)目
<br />
2.在跳出的彈框里選擇 Command Line Tool
,然后點(diǎn)擊 Next
<br />
3.在新的彈窗里填寫好 Product Name
炸宵,Language
選擇 C++
辟躏,然后點(diǎn)擊 Next
<br />
4.在新的彈窗里選擇項(xiàng)目路徑,點(diǎn)擊 Create
創(chuàng)建項(xiàng)目
到這里項(xiàng)目就創(chuàng)建好了土全。
2.配置相對(duì)路徑
軟渲染器需要對(duì)硬盤上的一些文件做一些 IO 操作捎琐,這時(shí)候就需要配置項(xiàng)目的相對(duì)路徑。
首先按照 Product
-> Scheme
-> Edit Scheme
的次序涯曲,打開一個(gè)彈窗野哭。
然后在彈窗里勾選 Using custom working directory
,并選擇項(xiàng)目文件所在路徑就可:
3.把源代碼拖進(jìn)去
因?yàn)楸卷?xiàng)目是零依賴的幻件,渲染方式是根據(jù)源代碼生成一張 tga 格式的圖片拨黔。因?yàn)槲覀兪莵?lái)寫軟渲染器而不是寫圖片編碼器的,所以直接把源代碼里的 tgaimage.h
和 tgaimage.cpp
拖到我們的項(xiàng)目工程里就可以了绰沥。
加上 main.cpp篱蝇,現(xiàn)在的工程目錄里只有三個(gè)文件
.
├── main.cpp
├── tgaimage.cpp
└── tgaimage.h
然后我們?cè)?main.cpp 里寫一些簡(jiǎn)單的代碼——?jiǎng)?chuàng)建一個(gè) 100x100 的圖片,在 (52, 41) 這個(gè)坐標(biāo)上畫一個(gè)紅的的點(diǎn)(rgb(255, 0, 0)
)
#include "tgaimage.h"
const TGAColor red = TGAColor(255, 0, 0, 255);
int main(int argc, char** argv) {
TGAImage image(100, 100, TGAImage::RGB);
image.set(52, 41, red);
image.flip_vertically();
image.write_tga_file("output/lesson00.tga");
return 0;
}
點(diǎn)擊 Xcode 左上角三角形的 build 按鈕徽曲,如果編譯成功并在 output
這個(gè)文件夾下生成一張名為 lesson00.tga
的圖片零截,就說(shuō)明環(huán)境配置成功了!
(紅點(diǎn)只有一個(gè)像素大秃臣,看不清可以點(diǎn)擊查看大圖)
<br />
<br />
今天在圖片上畫了一個(gè)點(diǎn)涧衙,明天我們就學(xué)習(xí)一下如何高性能的畫一條直線。
如果你覺(jué)得我寫的不錯(cuò)奥此,就給我個(gè)點(diǎn)個(gè)贊吧??弧哎!謝謝你,這對(duì)我真的很重要稚虎!