在前一篇文章中提到了光子映射算法具有高效,擴展性好,能輕易捕捉到各種光照效果(比如Monte Carlo ray tracing不易捕捉到的SDS路徑),但是它也存在很多問題,比如它本身是一個有偏的算法,boundary bias和topological bias通常能造成肉眼可見的artifact,這主要表現為灰暗的牆角,錯誤的顏色輝映以及漏光等現象。
針對這一問題,Havran等人在05年提出了以搜集光子射線代替搜集光子本身來解決boundary bias,該方法在采樣點切平面上創建一個圓形區域,經過此區域的photon ray將被搜集到,但是為了高效地進行photon ray gathering,需要建立復雜的數據結構比如ray map。緊接着,在07年由Herzog等人提出了photon ray splatting以代替photon ray gathering,該方法將整個光子映射算法流程倒了過來,即先進行eye tracing,再進行photon tracing。在eye tracing過程中,我們像raytrace那樣對視平面每個像素點發射射線,在擊中漫反射表面后將交點信息存放起來(若擊中鏡面則需存儲后繼射線的交點信息),一般用kd-tree作為數據結構;第二步photon tracing中,從光源每發射光子后,每擊中一個物體表面,就查詢之前建立好的eye sample kd-tree以確定對哪些屏幕像素點產生顏色值貢獻。在Herzog的算法中光源每次發射的是一個帶寬度的光子,如下圖:
因而當光子擊中場景時,會對一定范圍內的eye sample點產生顏色值貢獻,下圖顯示了標准光子映射(左),photon ray gathering(中),photon ray splatting(右)算法中光子搜集方式的不同:
可見,從eye sample(綠點)附近經過的photon ray都被搜集到了,而擊中背面的photon ray則可以利用一個可見性判別剔除掉,這樣就有效地解決了boundary bias和topological bias的問題。但是它仍然不能解決proximity bias,這種由於密度估計范圍r的不趨於零而存在的一種偏差,要解決這一問題,就必須想辦法將光子數量擴大到無窮大,以便將r減小,但是如何存儲同時怎么多光子呢?實際上,借用photon ray splatting中倒轉光子映射算法流程的思想,可以破除光子映射中內存的限制,原因很簡單,因為屏幕像素有限,所以要存下eye sample到內存是很輕松的事情,那么光子圖根本就不需要存儲,這樣要多少光子就可以發射多少光子。
08年,由Hachisuka等人提出了漸進式光子映射(Progressive Photon Mapping),通過第一步將eye sample組織成一個kd-tree結構,而后一輪輪地發射光子,每一輪將r減小一次,每一輪渲染一張圖片。隨着輪數的增多,光子數量越來越多,r的值越來越小,最終結果也越來越好,這樣PPM算法也使得光子映射能生成任意精准度的圖片,只要時間允許。由於倒轉了PM算法的步驟順序,PPM算法的光子搜集方法又從KNN變回到了直方圖估計,這是因為每一輪中估計半徑r一定是一個定值,雖然KNN估計在光子密度稀少處能更好地降低噪聲,但是由於PPM算法本身已經沒有了光子數量的限制,所以這點劣勢很容易以大量的光子數量扳回。有了PPM,我們甚至可以不需要final gathering,因為final gathering本身也極其耗時,且不能消除偏差,還沒有PPM算法自然簡潔。但是該算法也遠非沒有問題。由於預先存儲了eye sample,所以PPM無法很好地完成分布式光線跟蹤里可以完成的任務,如果是像反走樣這樣簡單的活還可以依靠在eye sample kd-tree中存下每個像素點的所有超采樣點來完成的話,那么要模擬反射模糊,景深,運動模糊就更麻煩了。
09年,還是Hachisuka,在PPM算法稍作改進,提出了SPPM(Stochastic Progressive Photon Mapping),該算法與PPM不同之處在於,在每一輪光子發射完畢后重新進行一次eye tracing,並且每次eye tracing都帶上一個隨機的擾動,讓每次構建的eye sample kd-tree中的數據都不一樣,下圖展示了這兩個算法的區別:
這樣做使得SPPM效率上略低於PPM,但是換來的是更加健壯和靈活,實際上SPPM在處理gloss反射的時候效果遠好於PPM。看到這里,我們可能會想,既然可以一輪輪地發射光子,那不倒轉整個PM算法流程也可以實現,即每次發射一定數量的光子,存起來,用完了再刪掉,再發射另外一撥光子。這確實是可行的,11年Claude Knaus等人就證明了這種方式和PPM算法具有同樣的魯棒性,由於和標准PM算法的極其相似,所以之前在標准PM算法中可用的擴展,這里也全部可用,這樣這種方法也很容易處理煙霧等介質的渲染。
至此,可以看出,光子映射算法中的兩個pass,代表了正向跟蹤和逆向跟蹤兩種思想,就像之前的提到過的Light tracing和raytracing一樣,兩個方向相互對稱,而它們每個都具有另一個所沒有的優點,bidirectional pathtracing連接了正向與逆向兩個路徑,達到了比pathtracing高很多的效率,photon mapping同樣利用了正向與逆向兩個方向的信息,不僅如此,它還重用了信息(光子圖),所以一般情況下能比bidirectional pathtracing收斂更快。
從古老的正向跟蹤算法Monte Carlo Light Tracing中,可以看到正向跟蹤普遍存在的問題,當場景空間很大,但是能被視點看到的部分卻很小的時候,會有大量的采樣點對最終圖像額顏色值貢獻很小甚至毫無貢獻。PM算法中同樣存在這一問題,當場景中光子分布很糟糕的時候(只有少部分光子能到達視點的可見范圍)該算法的收斂速度會變得非常之慢。受到Metropolis light transport的啟發,Fan Shaohua等人於05年將Metropolis准則引入了PM算法中的photon tracing中,使主要靠間接光照明的場景能達到更快的收斂速度;11年,Chen jiating等人在SPPM基礎上加入Metropolis准則,同樣提高了SPPM在這類場景的收斂速率。
最后貼上是幾張由PPM渲染的圖片,由於沒有了光子數量的限制,最終結果會比普通PM得到的結果更好: