實現光線追蹤


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)\)

推導過程復雜,作者不在此詳細闡述,有興趣的朋友可去這里查看


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM