Just My Life & My Work

[C++] 反射與折射

這次作業最大的難度就在於【反射】與【折射】的【遞迴】實做,
若沒有搞清楚折射和反射的公式,
必然無法做到想要的效果!
以下是我看了「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不斷累積的變數。

隨意留個言吧:)~

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

標籤雲