Rendering Final Project: PBRT+ (Progressive Photon Mapping)

[Introduction]  [Motivation]  [Implementation]  [Results]  [Discussions]  [Downloads]  [References]


Introduction

Progressive photon mapping(PPM)是photon mappimg(PM)的改良版。他的目的是要改善傳統photon mapping中,因為有限的記憶體導致無法儲存所有photon的問題。因此造成儲存的photon數量不夠來描述整個場景,也因此傳統photon mapping會有結果比較粗糙的情況。此外,PPM和傳統photon mapping一樣也能處理caustic的場景,而其他ray tracing的方法如path tracing、bidirectional path tracing、及Metropolis light transport等就無法做到很好的caustic效果。


Motivation

因為上課看到了photon mapping的結果還不錯,像是同樣為biased的方法的irradiance caching就會有結果一塊一塊的artifact。且其概念還蠻容易了解,所以我就對它還蠻有興趣的。於是我就選擇實做photon mapping的改良版,PPM,作為我的final project實作的主題。


Implementation

PPM最特別的地方有兩點:第一是它和傳統PM的步驟是顛倒的,PM是分成兩步驟---先從光源射出photon存成photon map,再對每個camera ray去找到最相近的鄰居的顏色去作平均當作自己的顏色;PPM則是先射出camera rays並紀錄它們和場景的交點(稱為hit point),之後再循環的去做射出photon的動作。可以用下圖表示:

方格是hit point,而圓點是photons。

PPM的主要概念就是利用累積的方式,來慢慢逼近每個hit point真正的顏色。所以會在每一輪射出固定量photons,並把它們的flux加到半徑包住它們的hit point上。此外,在每次加上photon的flux到某hit point時,會縮小其半徑,並在假設photon的密度不變下對它累積的flux做修正。用這個方式做下去,此paper提到他將會有個收斂的結果,同時也是就是真實的結果。

半徑縮小示意圖
R hat為新半徑
Tau_N hat為新flux,其中alpha為一個自訂的參數,預設為0.7

在儲存hit point的時候,必須用一個可以方便快速利用photon座標位置去找到包住他的hit point們的資料結構,像是kd-tree。但因為kd-tree是log(n)的搜尋時間,在數量大的時候很慢。故我使用了[2]中提到的spatial hash方法,可以直接利用點座標去找到需要的hit point,而且只需要constant time的搜尋時間。但我在實作時好像太浪費記憶體了,所以在sample數太多時(此時hit point也多)會有可能出錯。


Results

以下皆用64 samples/pixel、共16個photon tracing pass

cornell.png cornellbox.png

Discussions

我的結果不是很好,我猜想可能是photon的flux沒有做好的修正,所以導致都是很亮的點,場景render出來反而比較不smooth(photon mapping應該要有smooth的結果)。另外specular的部份沒有被完整的實作出來,我希望在寒假時能夠繼續把它完成。


Downloads

source.zip: 包含了所有我更改過的pbrt code、新增的code、以及測試用的場景。

References

  1. Hachisuka T., Ogaki, S., and Jensen, H. W. 2008. Progressive Photon Mapping. SIGGRAPH Asia 2008.
  2. Teschner, M. et al., 2003. Optimized Spatial Hashing for Collision Detection of Deformable Objects. VMV 2003.
  3. Course slides(Reflection models, Surface Integrator)