bidirectional pathtracing算法学习
?
??????bidirectional pathtracing算法是繼pathtracing算法以來的又一個突破。因為經典pathtracing算法有一個很大的問題就是效率極低,每個像素點發出的每個path必須擊中光源才會對該像素點的顏色值有所貢獻,否則這整條路徑都是無效的(對目標顏色值沒有任何貢獻),所以當光源很小的時候,pathtracing算法渲染的場景一般都很黑,并且噪點嚴重。還有一種特別的情況,就是光源被遮住的時候,整個場景主要由間接光照明的時候,pathtracing算法的效果也十分差勁,bidirectional pathtracing針對經典pathtracing算法的這些問題,不僅從視點出發發射射線路徑E,同時也從光源出發發射射線路徑L,最后將這兩條路徑上的點連接起來,計算每一對點的顏色貢獻度,再按一定的規則求得加權和,就是目標像素點的最終顏色了。如下圖所示:
?????? 談到bidirectional pathtracing,不得不提到一種更為古老的算法:Monte Carlo Light Tracing,這是一種與經典raytracing算法針鋒相對的算法。該算法的核心思想是:從光源發射粒子到場景,粒子每擊中一次物體表面就從交點處引一條射線到視點,若該點在屏幕表示范圍內且與視點無阻擋,則該交點的亮度值對屏幕上相應的像素點產生貢獻。同時,光線粒子以一定的幾率繼續在場景中游走(其游走方向由上一次交點處的物體表面屬性決定),當然,光線粒子也有一定的幾率被物體吸收(主要看物體的反射率),這時就回到起點,從光源發出另外一束粒子繼續之前的過程,下圖展示了Monte Carlo Light Tracing的算法過程:
如果說raytracing是逆向跟蹤算法的話,Light tracing就是正向跟蹤,可以看到在場景固定的情況下raytracing的計算量跟最終渲染圖片的像素點直接相關,而與場景的大小并無直接關系,Light tracing則跟場景大小有關,如果整個最終圖片只顯示整個場景的一小部分,就會有大量的粒子交點對屏幕像素毫無貢獻,或者貢獻很小,所以通常來說raytracing的效率要高于Light tracing。另一方面,我們可以想到在正向跟蹤的渲染算法中從一個漫反射表面正好有一束粒子朝鏡面表面射來的概率為0,因此它不能很好地表現(L->D->S->E)這類路徑,也就是鏡面反射現象(折射類似),而這正是raytracing這種逆向跟蹤算法所擅長的,并且因為一般的渲染算法中沒有實體的視點(視點一般都是一個理想的點,沒有大小),無法存儲直接擊中視點的粒子,所以無法表現鏡面高光,而這又是raytracing的看家本領之一。但是Light tracing也并非一無是處,因為它可以表現焦散現象(caustics),可以發現焦散的產生路徑(L->S->D->E)正好和鏡面反射的路徑對稱,所以單純的逆向跟蹤算法很難捕捉到焦散現象,正如正向跟蹤算法無法處理鏡面反射現象一樣(這里有個例外,經典pathtracing算法可以模擬焦散,因為它包含了L=0的路徑,這就要求光源必須是有體積的,而不是一個無大小的點,并且路徑L=0也有利于表現光源可視化等效果)。
注:L:(Light)光源
??? S:(Specular)鏡面或者透明表面
??? D:(Diffuse)漫反射表面
??? E:(Eye)視點
?
?????? 上文中提到了正向跟蹤和逆向跟蹤兩類離線渲染的算法,而?bidirectional pathtracing正是結合了這兩類算法的優點,達到更好的渲染效果和效率。之前的很多算法可以看成是這種算法的特殊情況,比如pathtracing就可以看出是bidirectional pathtracing中L路徑為0的特殊情況,下圖顯示了四種總長度為3的路徑
(a)可以代表pathtracing中的路徑;
(b)描述的是raycasting算法,Eye Path為2,也即從視點僅發射一束光線,不反彈,如果我們令Eye Path(圖中的t)在遇到鏡面表面或者透明表面的時候可以大于2,那么就成了經典的raytracing算法;
(c)中如果令s>=2的話,就可以描述Light Tracing算法;
(d)僅用于視點有體積的場所。
一般情況下,最好將Eye Path和Light Path大小都取為大于等于5,這樣才不至于遺漏一些現象(比如當Eye Path較小時不易表現鏡面反射等現象,當Light Path較小時不易表現焦散)。
還有一點需要說明的是Eye Path和Light Path上每一對點對最終顏色值貢獻度的權值的確定,有很多種權值確定方式,它們都只有一個目的就是讓圖片看起來更加真實,當然很多方法也比較復雜,我則是采用了最簡單的方法,均勻權值法,即每對點的重要程度一樣,而對于透明物體的處理效果也始終不好,這個問題目前也沒有想明白是什么原因(可能跟權值設定有關)。
最后貼上一張使用bidirectional pathtracing渲染的兩張圖片:
轉載于:https://www.cnblogs.com/starfallen/archive/2013/04/04/2999246.html
總結
以上是生活随笔為你收集整理的bidirectional pathtracing算法学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PL/SQL DEVELOPER 使用小
- 下一篇: 细学PHP 08 数组-2