2012-11-23 38 views

回答

13

我想通了從信息此頁面上的點點:http://cg.skeelogy.com/depth-of-field-using-raytracing/,特別是接近底部的圖表。我認爲我的表現略有不同,但這個概念非常簡單。

我可以解釋正在發生什麼以及如何實現它的一般想法(我會盡量簡潔)。光從各個方向上的任何給定點反射(一般來說),所以它實際上並不是在渲染點和你的眼睛之間的單一光線,而是離開渲染點並向眼睛擴展的光錐。你的眼睛/相機的鏡頭會傾向於彎曲這些光線,使錐體停止擴展並再次開始收縮。對於要完美對焦的物體,錐體應收縮到視網膜/框架上的一個點,但這隻能在距鏡頭一個特定距離處工作:在參考頁面中由「焦平面」指示的距離(儘管我認爲它應該是一個以眼球爲中心的球體,而不是一架飛機)。

對於焦平面前的任何物體,光錐會彎曲得更多:它會聚焦到視網膜/鏡框前面的一個點,然後再次開始擴展,以便在到達鏡框時,它不再是一個點,而是一個圓圈。類似地,對於焦平面後面的點,錐體會彎曲得更少,並且在到達框架時還不會收斂到一個點。在這兩種情況下,效果是單點是場景最終在多個像素上被抹掉。

爲了實現,您可以將這個想法放在頭上:代替將場景中的每個點渲染爲幾個像素,您可以將幾個附近的點渲染爲單個像素,這當然會發生什麼因爲來自相鄰點的「塗抹」光圈最終會重疊,因此每個都對像素有貢獻。

因此,這裏是我是如何實現它:

首先,定義一個光圈:在你的眼睛和平行的平面區域中心的視網膜/幀。光圈越大,DOF效果就越明顯。孔徑通常只是圓圈,在這種情況下,它很容易通過其半徑來定義。其他形狀可能導致不同的照明效果。

還定義「焦距」。我不認爲這實際上是它的正確名詞,但它是與眼睛完全對焦的距離。

要渲染的每個像素:

  1. 啓動由通過像素伸到場景鑄造等從眼睛正常光線。不過,不是將它與場景中的物體相交,而只是想要找到距離眼睛的距離等於所選焦距的射線上的點。將此點稱爲像素的焦點。
  2. 現在選擇光圈上的隨機起點。對於圓形光圈,非常容易,您可以選擇一個隨機極角和一個隨機半徑(不大於光圈半徑)。你想要在整個光圈上均勻分佈,不要試圖偏向中心或任何東西。
  3. 通過焦點從光圈上的選定點投射光線。請注意,它不一定會穿過相同的像素,沒關係。
  4. 按照您通常的方式渲染此光線(例如,路徑追蹤或僅找到最近的交點等)。
  5. 重複步驟2,3和4若干次,每次使用不同的孔徑上的隨機起點,但始終通過焦點投射。總結所有光線的渲染色彩值,並將其用作此像素的值(如常見,必要時除以恆定的衰減因子)。

當然,每個像素使用的光線越多,質量就越好。我一直在使用每像素約150光線來獲得體面的,但不是很好的質量。你可以看到少一點的效果(比如50或60條光線)​​,但更少的光線會在圖像中產生顆粒感,特別是對於焦點不清的物體。您需要的光線數量還取決於光圈大小:較小的光圈不需要儘可能多的光線,但您無法獲得儘可能多的模糊效果。

顯然,通過這樣做會大大增加您的工作量,實際上它會乘以每像素的光線數量,所以如果您在光線追蹤器中有任何優化工作要做,現在應該是個好時機它。好消息是,如果你碰巧有多個處理器可用,那麼一旦你找到像素的焦點,這是令人尷尬的平行。

多一點的解釋

下面的圖片應該給你發生了什麼事的想法,爲什麼它的作品了等同於真正發生在眼睛或攝像機。它顯示了兩個像素被渲染,一個像素顯示爲紅色,另一個像素顯示爲藍色。從眼睛通過每個像素到焦點「平面」的虛線是您在開始時投射的光線,以確定像素的焦點。半透明圓錐表示可以隨機選擇以渲染每個像素(像素1爲紅色圓錐體,像素2爲藍色圓錐體)的完整光線組。請注意,由於所有光線都穿過焦點,所以每個圓錐收斂到焦點處的一個點。

圓錐體的重疊區域表示場景中的點可能最終呈現給像素-1和像素-2:換句話說,被抹掉。由於每個錐體都是焦點「平面」上的一個點,因此這裏錐體之間沒有重疊,因此此距離處的點僅呈現爲單個像素:它們完全處於焦點。同時,越遠離焦點「飛機」(向前或向後),錐體傳播得越多,因此在任何給定點上錐體越多。因此,非常接近或非常遠的點將傾向於呈現爲大量不同的像素,因此它們將非常焦點。

Model of DOF implementation for raytracing.