[光線追蹤] 00 -- 前言 & 前置知識
前言
其實自己學習光追已經有挺長一段時間的了 (大概一年多?),? 途中嘗試過很多不同的光追模型和編程語言,? 但都因為效率不太好所以一直沒有寫相關的專欄.? 不過最近發(fā)現了一個效率挺高的模型,? 就覺得用這個模型作為專欄里的主要部分了,? 不過在介紹光追原理和大概結構的時候還會隨便提提其他模型.
專欄里的主要編程語言就選用速度很快的 C++ 了,? 但是由于 C++ 寫起來還是挺麻煩的,? 所以也許專欄里有部分代碼會選用其他語言 (比如說 python) 作為示例,? 不過實際上實現的最后還是 C++ 就是了.? 不得不說明的一點,? 自己真的不太會寫 C++,? 如果實際代碼里有什么可以優(yōu)化或者真的寫得一團糟的地方,? 非常歡迎指出.
關于排版的話,? 因為屑阿b在一個專欄里只能放 100 張圖片,? 而數學公式也算是一張圖片,? 所以有些地方不得不使用 unicode 字符來代替 latex 公式了.? 但是我發(fā)現有很多地方都不能顯示 unicode 的上標箭頭 (如下圖所示),? 所以向量就使用帶顏色的粗體表示了:??? u

關于光追有一個不得不說的東西:? 這里討論的光追是指一種渲染手段,? 而不是對物理的模擬仿真.? 也就是說為了追求模型的簡便和計算的速度,? 有某些地方需要進行必要的假設,? 而這些假設會使渲染結果與真實的場景產生偏差.? 所以如果是在追求對真實場景的模擬仿真的話,? 這篇專欄是非常不合適的.? 另外,? 在專欄里進行這種會產生偏差的假設時,? 會用紅色大字標明.

前置知識
因為光追涉及到很多向量計算,? 所以相應的向量知識是必須的 (下面會進行一個復習的動作).? 而對推導光追模型的過程需要運用微積分的知識,? 所以如果想知道具體數學細節(jié)的話,? 看懂微積分是必須的,? 但僅限于看懂就行了,? 并不會涉及微積分的求解.? 跟傳統(tǒng)的光柵化渲染不一樣的是,? 在光追里線性代數不是必須的,? 倒不如說基本上不會遇上.
復習:??
在三維空間里,? 任意一個向量都有 3 個分量:? .
向量的模長定義為? .
向量的歸一化返回方向與原向量相同但模長為1的向量:? .
兩向量之間的點乘 dot 定義為向量之間逐元素乘積的和:??,? 點乘與向量的模長和夾角有關:??
.
兩向量之間的叉乘 cross 返回一個向量,? 并且返回向量與原來的兩個向量垂直,? 模長與原向量的模長和夾角有關:? ,? 叉乘的計算為:??
,? 并且叉乘是不可以左右互換的.

幾種基本的類型和方法
數學上的向量可以在編程里使用數組實現,? 并且在一些編程語言里都自帶實現了數組,? 比如說 python 的 list?或?numpy 的 ndarray,? julia 的 Vector,? C++ 的 std::vector.? 這些數組都是可以改變長度的,? 但是向量本身是不變長的,? 所以為了優(yōu)化性能,? 應該使用不可變長的數組作為向量類型.? 在?julia 里可以使用 StaticArrays 包,? 而在 C++ 里可以使用 glm 庫 [github.com/g-truc/glm].? 在這里我就多此一舉自己實現了:
Vec2 是為了計算紋理或采樣的,? Vec3 就是計算光追里最主要的類了.? 這里使用雙精度浮點數是因為計算光追的精度要求較高,? 如果使用單精度浮點數雖然計算速度較快,? 但會產生較大的誤差,? 從而造成渲染錯誤.
另外需要實現兩個向量類的四則運算:

然后實現向量的幾何運算:

為了某些增加某些計算的速度,? 應該提供某些不饒遠路的幾何運算:? 比如說 abs2 直接返回模長的平方,? 亦即向量元素的平方和,? absnorm 修改向量的模長到1并且返回原來的模長:

另外別忘了還有球極坐標和相應的逆方法:

最后還有一個實用的東西:? 因為有時候會在幾何表面處計算臨近的坐標,? 所以在幾何表面建立局部坐標系是很有用的.? 一般來說幾何表面會提供一個法向量:? 法向量是一個垂直于表面并且模長為1的向量,? 但是這樣是不足以建立局部坐標系的,? 所以還需要一個在表面上的紋理向量,? 但紋理向量不存在時可以直接選取全局坐標的 x軸,? 但如果法向量平衡與 x軸 計算會出問題,? 這時候選取?y軸 就行,? 下面是局部坐標系的實現:

其中 LocalCoord::at 是把局部坐標轉為全局坐標.
最后,? 儲存渲染緩沖區(qū)和采樣集都需要二維數組,? 所以自己搓了一個 Buffer2D<T>,? 大概是這個樣子的

具體實現可以參考倉庫里的 utils.? (倉庫鏈接: github.com/nyasyamorina/nyasRT)
另外關于采樣的實現也可以參考倉庫里的 samples.

寫了一大篇廢話,? 總之,? 下一篇開始就是開始推導并實現光追算法了.
最后再推一下倉庫:?github.com/nyasyamorina/nyasRT
最最后再推一下澀弔圖群:??274767696