關於【Ray Tracing】是一門很值得研究的學問,
在實做過程我遇到幾個瓶頸:
遞迴、折射、反射、鏡射光、散射光等,
尤其是【遞迴】如果沒有清楚的腦袋,
很難將後四者給兜起來。
首先我們來看一條「主光線」如何遞迴:
我實做時遞迴函式原型為:
Primitive* Raytrace(Ray& a_Ray, Color& a_Acc, int a_Depth, float a_RIndex, float& a_Dist)
這是一個raytrace的函式,透過它來做光線的遞迴,回傳圖元指標。
Ray& a_Ray:主要光線
Color& a_Acc:累積的顏色
int a_Depth:遞迴的深度
float a_RIndex:介質的折射率
float& a_Dist:光的距離
整體遞迴結構如下:
|
以上累積顏色的方式稍有不同:
[1]:a_Acc = Color(1, 1, 1);
[2]:a_Acc += diff * prim->GetMaterial()->GetColor() [* light->GetMaterial()->GetColor()];
[3]:a_Acc += spec * light->GetMaterial()->GetColor();
[4]:a_Acc += refl * rcol * prim->GetMaterial()->GetColor();
[5]:a_Acc += refr [* rcol * prim->GetMaterial()->GetColor()];
累積的定義可仔細調整。
遞迴的次數會影響Screen的成像,
我實際跑出結果:
可以從以上影像觀察到:
第一次只有【主光線】,
第二次多了【次光線】反射和折射,
第四次有……(不會講XD自己看~),
第五次之後成像就定型了,
第十次是前幾次較大的亮度。
遞迴需要花很長的時間,
以512*512像素來說,
總共有262144條主光線,
若遞迴次數為3的話,
每一條主光線會產生(2^3-1)-1=6條次光線,
那麼整個程式一共會產生262144*7條光線,
大概是180萬條光線,
短時間內可以運算完畢,
即使遞迴深度只有5次也可以得到不錯的效果。
當然剛才計算的是最差的結果,
因為並不是每一條光線都會產生「反射」和「折射」,
這必須端視光線擊中的物體特質來決定,
也就是說若場景中所有物體都有反射和折射性質,
那麼物體數量一多就會跑得相當吃力!
總之,玩過就知道:)~







Comments on: "[C++] 光線追蹤 (Ray Tracing)" (1)
[…] 在這呢~我想要將我去年所做的成果貼上來,這回合是光線追蹤動畫 (Ray Tracing Animation),想要知道動畫如何被製作出來,首先必須先參考我去年寫的光線追蹤 (Ray Tracing)。 […]
讚讚