C++實現光線追蹤之詳解
[參考文章]http://www.cnblogs.com/miloyip/archive/2010/03/29/1698953.html

1. 本文簡介
作者正大三,剛好選修到計算機圖形學這門課,基於興趣,便試着實現全局光照的效果,由此,寫下此篇文章。
2. 光線追蹤
所謂光線追蹤,是指從眼睛出發,經過圖像平面每一像素,投射光線到場景中,求該光線與場景中幾何圖形的最近交點,然后求該交點的顏色屬性,並將該顏色值記錄下來,再根據相交點的材質判斷性地進行反射、折射等現象繼續追蹤計算,最終把多次追蹤交點顏色值的結果混合得到最終該像素的顏色值。(本文皆是介紹反向追蹤)

3. 場景說明
4.1 攝像機
此次實驗,本人將攝像機放置於世界坐標系下的Vec3(0,5,15)下,圖像平面置於Vec3(0,0,-1)處。注,為了簡化,直接將圖像設置width,height一致,均為600。

圖一
特別注意:\(|front| = 1\)
4.2 場景
本實驗中,場景由兩個球以及一個無限平面組成。
Sphere1:
Sphere(Vec3(-10,10,-10),float(10))
參數一:球心
參數二:球徑
Sphere2:
Sphere(Vec3(-10,10,-10),float(10))
Plane:
在數學表達上,無限平面可表示為\(nP=d\),其中n為平面法向量,d為原點到平面的最短距離。
Plane(Vec3(0,1,0),float(0))
4.3 圖像中坐標的轉換
最初,圖像是600*600的平面,左上角為原點。現先轉換為以左下角為原點的[0,1]范圍內的平面。
左上角為原點且范圍為[0,600]:
\(X = X\)...(1)
\(Y = Y\)...(2)
左下角為原點且范圍為[0,1]:
\(X = X/width\)...(2)
\(Y = 1-Y/height\)...(2)
圖像中心為原點且范圍為[-1,1]:
\(X = 2X-1\)...(3)
\(Y=2Y-1\)...(3)
4. 過程詳解
(1)對於圖像平面,自左向右,自上而下的經過每一像素投射光線
(2)計算光線與場景中幾何圖形的最近交點,都無交點即直接返回黑色,進行(5),否則進(3)
(3)取樣 即計算最近交點的顏色屬性
(4)計算反射光線繼續追蹤,回到(2)。
(5)賦像素予顏色值,回到(1)
4.1 步驟一之生成光線
由圖一可知,
\(Ray.dire = SampleVector+front\)...(4)
\(SampleVector=Vec3(X,Y,0)\)...(5)[注:此時是以中心為原點了]
即可得到初始化的Ray對象Ray(eye.origin,Ray.dire);

轉換為中心為原點計算光線原因如下:
4.2 步驟二之計算最近交點
- 光線
\(R(t)=eye.origin+tD\)(t為參數) - 平面
\(nP=d\)
1)判斷光線與法向量n是否垂直
2)不垂直即可計算交點
光線與無限平面的法向量位置情況:

由上圖可知,當\(n·Ray.dire>=0\)時,沒有交點;否則,有交點。
3)交點的計算:
\(D=(d-eys.origin·n)/(t·n)\) - 球
推導過程復雜,作者不在此詳細闡述,有興趣的朋友可去這里查看
