天天看點

【光線追蹤】光線追蹤重投影方法(Ray Tracing Reprojection)光線追蹤重投影方法

光線追蹤重投影方法

重投影這項技術一般用于時間性幀複用技術上,例如TAA(Temporal Anti-Aliasing)反走樣或者抗鋸齒技術。光線追蹤使用時間性幀複用技術一直覺得是個難題,比光栅渲染的要麻煩,是以提出一種光線追蹤重投影方法,用來支撐光線追蹤使用時間性幀複用技術。讀這篇文章最好先對TAA這類技術的算法流程有了解。

1.TAA抗鋸齒技術簡介

先簡單介紹下TAA抗鋸齒的原理,在遊戲中,目前渲染一幀畫面的單獨拎出來看,是有鋸齒的(物體邊緣有狗牙),而TAA則将曆史幀作為抗鋸齒的參考資料(可以一幀也可以多幀)。為目前幀的一個像素找到它在曆史幀中對應的那個像素,做個權重混合。如果用多個曆史幀的話,那麼越久遠的幀在混合中使用的權重越低。

大緻的原理圖如下:

【光線追蹤】光線追蹤重投影方法(Ray Tracing Reprojection)光線追蹤重投影方法

是以TAA技術的重點之一就是上圖那根紅色箭頭,如何為目前像素找到它在上一幀中對應的位置。實作這個紅色箭頭的就是重投影技術。

2.重投影技術的簡介

重投影技術,将目前像素進行投影,分為兩種:

  • 反向重投影:從目前像素反向尋找其在曆史幀中的位置。
  • 前向重投影:從曆史像素前向尋找其在目前幀中的位置。

我認為區厘清楚這兩種方向不同的方法非常關鍵和重要。

TAA抗鋸齒技術這類時間性複用技術,幾乎隻用于光栅渲染,很少在光線追蹤中用到。并不是光線追蹤渲染的圖無鋸齒,而是光線追蹤渲染無法提供光栅渲染在重投影技術中所需要的資料,是以TAA技術無法或者很難直接從光栅渲染中套用在光線追蹤渲染中。

重投影在光栅渲染中已有成熟的方法,但是在光線追蹤中的相關研究較少,缺乏通用的方法。光栅渲染做重投影通常用的是反向重投影的方法。例如使用運動矢量(Motion Vecter)方法或者通過投影矩陣反推的方法。

但是運動矢量和投影矩陣方法都是用到光栅渲染過程中可以天然産生的資料,而光線追蹤渲染的方法又大大不同,這些資料都沒法在渲染過程中天然獲得。

3. 光線追蹤前向重投影方法

因為接觸到查閱到的大多都是反向重投影的思路,是以我想了很久為光線追蹤做重投影的路子,都覺得太繞太複雜。

後面讀文獻才知道還有前向重投影這個方向。我就想反過來從曆史像素推出它大概會在目前幀跑到哪裡行不行。答案是可以的,前向重投影的思路能夠直接使用光線追蹤過程中産生的資料。

先假設這個光線追蹤場景:場景中物體都是靜止不動的,前後幀隻有攝影機是運動的,重投影隻用到一幀曆史幀。

原理圖:

【光線追蹤】光線追蹤重投影方法(Ray Tracing Reprojection)光線追蹤重投影方法

具體方法流程:

  1. 該重投影方法需要緩存曆史幀碰撞點坐标。
  2. 周遊曆史像素時,首先取出像素對應的曆史碰撞點坐标,利用目前錄影機參數将該坐标從世界坐标系變換到目前幀的錄影機坐标系中。
  3. 然後利用相似三角形理論将該曆史碰撞點的三維坐标變換為目前幀中的 UV 坐标,請看下圖。
    【光線追蹤】光線追蹤重投影方法(Ray Tracing Reprojection)光線追蹤重投影方法
  4. 在錄影機坐标系中将錄影機與螢幕像素平面和曆史光線碰撞點連接配接成相似三角形,再利用攝影機到像素平面的距離求該碰撞點在像素螢幕中的x 和y 坐标(即目前幀的UV坐标)。
  5. 接着将 UV 坐标轉換為 NDC 标準裝置坐标,再根據目前視窗尺寸計算得到光栅坐标。該光栅坐标即曆史像素映射到目标幀中的像素坐标,若映射結果超出目标幀的像素範圍則棄用;最後将曆史像素顔色值存入重投影緩存中,用于與目前渲染幀像素做權重混合。

算法流程圖:

【光線追蹤】光線追蹤重投影方法(Ray Tracing Reprojection)光線追蹤重投影方法

效果:

能夠實作光線追蹤的重投影算法,那TAA抗鋸齒當然能做。我覺得有一塊更适合用在光線追蹤上的就是降噪,光線追蹤采樣數低的時候噪點非常嚴重,結果重投影技術去研究降噪技術,是一種省時間省性能的方法。

下圖是我做的對光線追蹤采樣光線數量隻有一條的時候,用了上面重投影技術做的時間性降噪方法,前後對比還是比較明顯的。

【光線追蹤】光線追蹤重投影方法(Ray Tracing Reprojection)光線追蹤重投影方法

因為并沒有做額外幀的渲染,是以性能額外消耗很少。不過采樣數隻有1,也是盡力了,把采樣次數提高一點的話,降噪效果也挺好,隻是1的時候差異很明顯。

4.讨論

上面的方法也是限定了場景的:場景中物體都是靜止不動的,前後幀隻有攝影機是運動的,重投影隻用到一幀曆史幀。

如果場景中物體會發生變換的話,我沒有繼續研究下去,不過我的想法是,現在方法是隻有錄影機在運動,如果物體發生變換的話,那就是與錄影機發生相對運動。那就記錄物體的變換矩陣,把曆史幀物體的碰撞點坐标變換到目前幀的新三維坐标,再使用上面介紹的算法去計算曆史像素其在目前幀中的目标像素點。

有其他光線追蹤重投影想法的,或者我的算法有啥缺點改進的,都歡迎找我交流。