我遇到了我正在開發的光線追蹤器中的一個有趣問題。我的場景中的對象存儲在邊界卷層次結構中。每個單獨的對象都封裝在層次結構的葉節點的邊界框中,並具有與其關聯的矩陣轉換。帶邊界體積層次結構的光線追蹤對象矩陣變換
現在,我被教導要在光線追蹤中對物體進行矩陣變換的方法是,通過對象矩陣的逆來變換每條光線,然後查看是否存在相交。在僞代碼(和沒有BVH樹)它是這樣的:
float minimum_distance = FLOAT_MAX;
Intersection closestHit = null;
for(each object in scene)
{
Matrix transform = object.transform();
Matrix inverse = transform.inverse();
Ray transRay = transformRay(eyeRay, inverse);
Intersection hit = CollisionTest(transRay, object);
if(intersectionFound)
{
if(hit.distance() < minimum_distance)
{
closestHit = hit;
}
}
}
Shade(closestHit);
由於沒有邊界結構到場景中的對象,你可以通過每一個循環,並通過每個對象的矩陣變換光線測試。但是現在想象一下BVH樹的下列情況:
ROOT
Left Box Right Box
| |
V V
object A object B
現在讓我們說我們有一個eyeRay交叉口只有正確的方框。射線只會檢查位於右側框中的交叉點對象,並完全忽略左側框中的任何對象(這是將對象置於像這樣的層次結構中的主要優點......以避免不必要的檢查)。
但是,左側框中的對象A具有與其關聯的縮放變換,當應用該對象時,該對象將伸展對象A以使其跨過右側框區域。如果光線被允許檢查自身與場景中的每個物體,你會發現,當物體A的變換的逆應用於光線時,會找到相交點。然而,光線永遠不會被允許進行這種轉換檢查,因爲未轉換的對象A正好坐在左邊的框中。因此,交集將被錯過,結果將是一個部分渲染的對象A.
所以我的問題是我將如何解決這個問題?我不想放棄使用邊界卷層次結構,但我不明白它如何與上面的反射光線算法兼容。有什麼想法嗎?
不幸的是,在光線跟蹤中,轉換對象而不是光線是不可取的。假設您的物體是球體 - 轉換球體並將其與未轉換的射線相交將需要提出可與任意球體配合使用的相交算法。變換射線意味着您可以始終使用常規的球面射線相交測試。 此外,我不能只是通過對象轉換來轉換邊界框,因爲可以說左邊的框中有2個對象,其中有2個不同的轉換。我是否必須迭代轉換每個邊界框? – user1855952
所以如果你在一個盒子裏有兩個物體,你要做的是計算兩個〜轉換的物體上的邊界。現在,您可以將未轉換的光線與此盒子進行比較,如果碰撞,則將光線轉換爲物體1的空間,檢查碰撞,然後將光線轉換爲物體2的空間並檢查碰撞。將工作正常。 –