最新的關於BSP技術的深入剖析與詳解3(轉)

post0發表於2007-08-12
最新的關於BSP技術的深入剖析與詳解3(轉)[@more@]

  第三節 室內場景中光照運算

  關於Radiosity的演算法最早是由Goral、Cindy M、Torrance、Kenneth E、Greenberg、Donald P、Battaile和Bennett在論文《Modelling the interaction of light between diffuse surfaces》提出的。他們使用Radiosity來模擬能量在漫反射表面之間進行傳送,漫反射表面對照到表面上的光線在所有的方向上都進行相同的反射,和它相反的是鏡面反射表面,它只在反射方向上傳播反射光。由於漫反射表面的這個特性,這就意味著對於所有的觀察角度而言看起來表面都是相同的,這樣對於場景中的每一個表面只需要進行一次光照運算,而且可以在場景的預渲染時進行,因此這項技術被大量的3D遊戲所採用。

  下面我再簡短的講解一下Radiosity是如何工作的,而將主要的精力放在如何使用BSP樹來加速Radiosity的計算,對於Radiosity的詳細介紹請參考前面的章節。Radiosity技術是設計用來使場景中光照看起來更加真實和光滑,如果我們使用一個一直向前傳播而不考慮反射的光照模型,那麼當場景中的燈光照亮場景中的物體時,並不會計算遠處經過反射過來的光線,這樣場景中的陰影看起來非常尖銳而物體表面也看起來非常不真實。為了使用radiosity技術我們需要把場景分割成一塊一塊很小的部分,每一部分我們稱它為patch,每一個patch都有一個初始化的能量級別,如果它不是一個燈光這樣的發光體的話通常為0,有許多方法來分配場景中的能量,這裡我們將要使用的方法稱為互動式radiosity。這個方法的過程是我們從場景中未傳送能量的級別最高的patch開始傳送能量,能量經過傳遞後將不再傳送能量的patch的等級設為0,重複這個過程直到場景中的每一個patch的能量等級都小於一個預定值為止。

  當能量從一個patch(j)開始傳送到另一個patch(i)時我們使用下面的公式:

  Bi = Bi + Bj * Fij * Ai / Aj

  這裡Bi = patch(i)的能量級別   Bj = patch(j)的能量級別

  Ai= patch(i)的作用區域  Aj = patch(j)的作用區域

  Fij = patch(i)與patch(j)之間的係數

  在公式中係數Fij是由以下公式來確定的:

  Fij = (cos qi * cos qj) / d2 * Hij

  這裡Fij = patch(i)與patch(j)之間的係數

  qi = patch(i)與patch(j)法線之間的夾角

  qj = patch(i)與patch(j)法線之間的夾角

  d = patch(i)與patch(j)之間的距離

  Hij = patch(i)與patch(j)之間的可見性係數。如果在兩個patch之間只有一條光線可以跟蹤,這個值為1,如果沒有光線可以跟蹤為0。一般情況下由於每一個patch都不是一個點而是一個區域,因此光線有很多條。

  從上面的公式中我們可以看到在場景中進行radiosity計算是非常耗費時間的。這個函式的複雜度為O(n3),這裡的n為場景中patch的數量。由於對於場景中每一個patch你需要傳送最少一條光線到其它patch上,因此需要對場景中的幾乎所有的多邊形都進行光線跟蹤計算。在上面的公式中係數H的計算非常耗費時間,下面我們將看一下如何在BSP樹中對它的計算進行最佳化。

  

  BSP樹中的radiosity計算

  在進行場景中的光照計算之前需要把場景中的面分割為patch,一個方法是在開始的時候設定每一個patch為預定的大小,當計算每一個patch的能量時,如果在patch上的能量足夠大,對這個patch進行分割。不過這個方法是非常耗費時間的,因此必須尋找一個更好的方法來透過BSP樹對計算進行最佳化。

  在radiosity的一般演算法中場景中的每一個光源都被看作為一個或多個patch,這裡我們可以改進一下,將每一個光源放在它所位於的葉節點中,接下來每一個光源都傳送自己的能量到場景中所有的patch上,當這個過程完成後radiosity計算也就結束了。為了使最後的結果看起來更好可以使用一種稱為“漸進精選”(progressive refinement)的技術來對這個方法進行很小的修改。在每一次過程中,葉節點中具有高能量的patch將傳送能量到其它低能量的patch上,這樣做的結果是高亮度的patch將傳送能量到處於陰影中patch上。這是因為在實際生活中並沒有真正黑暗的地方,它多多少少要獲得一些其它物體反射過來的光亮。

  由於計算非常耗費時間需要做一下最佳化,使用渲染BSP樹時獲得的PVS資訊可以在選擇哪些patch將接受能量時剔除一些無用的計算。因為在計算PVS時使用了相同的方法來進行光線跟蹤。

  透過場景來分配能量的演算法如下:

  l 函式RADIOSITY

  l 引數:

  l Tree ? 進行radiosity計算的BSP樹。

  l 返回值:

  l None

  l 功能:

  l 在場景中的patch之間傳送能量。

  RADIOSITY (Tree)

  1 for(each leaf L in Tree)

  2 for(each light S in L)

  3 for(each leaf V that is in L’s PVS)

  4 Send S’s energy to the patches in V

  l 下面語句5是為了讓地圖編輯者在任何時候都可以檢查場景渲染的效果,如果他感到看起來已經足夠好了可以中斷能量的傳播。

  5 while(not looks good enough)

  6 for(each leaf L in Tree)

  7 for(each leaf V that is in L’s PVS)

  8 Send energy from the patch with the most unsent energy in L

  to all patches in V.

  

  複雜度分析

  這個函式的運算費用實在是太高昂了,可以稱為時間殺手,在最壞的情況下每一條光線將不得不檢測場景中的每一個多邊形,此時複雜度為O(n3),這裡n為樹中patch的數量。一般情況下由於進行了最佳化可以減少大量的計算,但是減少多少並不能計算出來,因為這依賴於樹結構的複雜度。

  上面的函式給出了一個充分利用BSP樹的優點來加速場景光照運算的方法,尤其是可以顯著的減少光線跟蹤的計算量,而且地圖設計者可以來決定當場景渲染時如果渲染的效果可以接受中斷渲染迴圈。這對地圖的預渲染實在是太方便了,執行的時間可以根據渲染的效果來決定。

  

  第四節 BSP樹的預渲染

  現在我們需要完成一個完整BSP引擎的預處理過程,下面的演算法顯示如何將場景渲染到BSP樹中。

  l 函式RENDER-SCENE

  l 引數:

  l Scene ? 被渲染的場景

  l 返回值:

  l 一個BSP樹。

  l 功能

  l 預渲染來獲得一個包含場景資訊的BSP樹。

  

  RENDER-SCENE (Scene)

  l 使用描述場景中圖元的物體來渲染BSP樹。

  1 GeometryPolygons = {}

  2 for (每一個包含場景圖元的物體object O)

  3 GeometryPolygons = GeometryPolygons U O.PolygonSet

  4 GENERATE-BSP-TREE (Tree.RootNode, GeometryPolygons)

  l 分配葉節點上的取樣點。

  5 DISTRIBUTE-SAMPLE-POINTS (Tree.RootNode, {})

  6 TRACE-VISIBILITY (Tree)

  7 for 每一個場景中的靜態物體object O

  8 for 物體O中每一個多邊形P

  9 PUSH-POLYGON (Node, P)

  l 函式CREATE-PATCHES是一個未定義的函式,由於我們的解決方案效率並不是太好,因此沒有對它進行詳細的介紹。

  10 CREATE-PATCHES (Tree)

  11 RADIOSITY (Tree)

  

  複雜度分析

  函式的複雜度如下:

  函式 最壞情況 一般情況 描述

  GENERATE-BSP-TREE O(n2 lg n) O(n2) n為場景中多邊形的數量

  DISTRIBUTE-SAMPLE-POINTS Q (np + xy) Q (np + xy) n為樹中多邊形的數量,p為樹中典型點的數量,x和y為分割面的寬度和高度。

  TRACE-VISIBILITY O(n2) O(n lg n), n為樹中多邊形的數量。

  RADIOSITY O(n3) O(n2 lg n) n為樹中patch的數量

  

  在一般情況這一列中顯示了演算法通常所需執行的時間,對演算法時間影響最大的是函式RADIOSITY,它使整個演算法的複雜度趨向於O(n3)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-951986/,如需轉載,請註明出處,否則將追究法律責任。

相關文章