我正在寫一個3D光線追蹤器作爲個人學習項目(Enlight),並遇到了一個有趣的問題,涉及到在光線和物體場景之間進行相交測試。高效光線追蹤的數據結構
的情況是:
- 我有一個數字,光線可以與(球狀,盒,飛機等),以及它們的組相交的圖元。總的來說,我稱之爲這些場景對象。
- 我希望能夠通過將對象包裝在一個
Transform
對象中來使場景中的對象具有任意仿射變換(重要的是,這將允許在場景中的不同位置使用相同基元的多個實例,因爲基元是不可變的) - 場景中的對象可以被存儲在邊界體積層級(即我做空間分割)
- 我的相交測試與
Ray
對象表示的部分射線段工作(開始矢量,歸一化的方向矢量,開始距離,結束距離)
問題在於,當光線碰到Transform對象的邊界框時,看起來像對其中包含的已轉換基元進行相交測試的唯一方法是將Ray
轉換爲轉換後的座標空間。這很容易,但如果射線沒有擊中任何變形的物體,我需要回退到原始的Ray
繼續追蹤。由於變換可以嵌套,這意味着我必須爲每個已完成的相交軌跡保留一大堆Ray
。
這當然是整個應用程序的內部循環和主要性能瓶頸。它會被稱爲每秒數百萬次,所以我渴望儘量減少複雜性/避免不必要的內存分配。
有沒有一種巧妙的方法可以避免必須分配新的Ray
s /保留Ray
堆棧?
還是有一個更聰明的方法來完成這一切?
我不確定這會比內存分配更快,但是您可以試着想出一個高效的變換反演算法,然後在退出當前對象時將當前射線與逆變換相乘。 –
@伊萬 - 有趣的想法。我想這可能會稍微快一些,但我會擔心複合數值精度問題..... – mikera
您可以預先計算並緩存每個對象的變換和逆變換(即矩陣對象)(以及組中的對象),它們將轉換爲全局框架並從全局框架轉換。這樣您就不需要嵌套層次結構,因爲您可以直接對每個對象執行命中測試。即將射線轉換爲對象的框架,然後轉換回全局框架中的命中點。我在我的追蹤器中執行此操作:http://github.com/danieljfarrell/pvtrace –