這次作業最大的難度就在於【反射】與【折射】的【遞迴】實做,
若沒有搞清楚折射和反射的公式,
必然無法做到想要的效果!
以下是我看了「Reflections and Refractions in Raytracing」論文所得到的結論:
以上公式直接套進程式中,
就可以得到預期的結果喔!
而參考的程式碼如下:
1// calculate reflection
2float refl = prim->GetMaterial()->GetReflection();
3if(refl > 0.0f){
4 vector3 N = prim->GetNormal(pi);
5 //reflection vector
6 vector3 R = a_Ray.GetDirection() – 2.0f * DOT(a_Ray.GetDirection(), N) * N;
7 Color rcol(0, 0, 0);
8 float dist;
9 Raytrace(Ray(pi + R * EPSILON, R), rcol, a_Depth + 1, a_RIndex, dist);
10 a_Acc += refl * rcol * prim->GetMaterial()->GetColor();
11}
1// calculate refraction
2float refr = prim->GetMaterial()->GetRefraction();
3if(refr > 0){
4 float rindex = prim->GetMaterial()->GetRefrIndex();
5 float n = a_RIndex / rindex;
6 vector3 N = prim->GetNormal(pi) * (float)condition;
7 float cosI = -DOT(N, a_Ray.GetDirection());
8 float cosT2 = 1.0f – n * n * (1.0f – cosI * cosI);
9 if(cosT2 > 0.0f){
10 //refraction vector
11 vector3 T = (n * a_Ray.GetDirection()) + (n * cosI – sqrtf(cosT2)) * N;
12 Color rcol(0, 0, 0);
13 float dist;
14 Raytrace(Ray(pi + T * EPSILON, T), rcol, a_Depth + 1, rindex, dist);
15 a_Acc += rcol;
16 }
17}
讓我一直搞不懂的是紅色的部份,
為何一定要加反射R(折射T)向量到交點pi再乘上EPSILON0.0001?
拿掉紅色部份後效果就會變得很差。
粗體字Raytrace是Ray持續遞迴的函式,
粗體字a_Acc是Color不斷累積的變數。


隨意留個言吧:)~