最新的關於BSP技術的深入剖析與詳解3(轉)
最新的關於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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於Java中列舉Enum的深入剖析Java
- 【恩墨學院】深入剖析:關於cache buffers chains的經典案例處理詳解?AI
- 最新SS園設計模式例項剖析與深入解讀教程設計模式
- 轉:關於SGA_MAX_SIZE與SGA_TARGET的詳解
- 剖析外掛技術 (轉)
- 最新的B/S開發技術 (轉)
- 【釣魚】與【反釣魚】的技術剖析
- pjlib深入剖析和使用詳解
- 關於IT,關於技術
- 關於cookie的詳解Cookie
- 深入剖析全鏈路灰度技術內幕
- Delphi中關於TApplication類的詳解 (轉)APP
- 關於C++中物件與類的詳解及其作用詳解C++物件
- 關於技術的選型
- 關於技術分享的思考
- 深入剖析Redis系列(三) - Redis叢集模式搭建與原理詳解Redis模式
- 3D地形相關技術 (轉)3D
- 關於無線通訊的核心技術詳細介紹
- Mysql 關於event的詳解MySql
- 關於Oracle的技術問答Oracle
- 關於FSO靜態生成技術的應用範圍之解決思路 (轉)
- DirectShow技術描述與應用(3) (轉)
- Java RMI技術詳解與案例分析Java
- SVG中的動畫技術(3) (轉)SVG動畫
- XML與其相關技術(1) (轉)XML
- 關於視訊的編解碼與傳輸技術,你想知道的都在這裡
- 基於PHP與XML的PDF文件生成技術(摘要) (轉)PHPXML
- 關於資料庫open的深入探究(轉)資料庫
- 深入解讀ESB與SOA的關係
- Delphi 中的 XMLDocument 類詳解(9) - 關於 HasChildNodes 與 IsTextElementXML
- CSS基礎篇–CSS3圖片翻轉動畫技術詳解CSSS3動畫
- 關於技術分享的一點感悟
- 關於.NET中的Server push技術Server
- 關於技術選型的問題
- 關於SSL裝置的詳解
- Mysql關於procedure、function的詳解MySqlFunction
- Windows 關於Robocopy的使用詳解Windows
- 關於Oracle的提示詳解(1)Oracle