2012/10/07

Vray最佳設定 ─ Raycasting




Via:http://renderstuff.com/
作者:Anton, Max
翻譯:Hammer Chen


這篇教學將回答以下問題:
如何避免當記憶體不足時所造成3ds max當機的問題?
V-Ray在算圖的時候當機時該怎麼辦?
如何處理V-Ray遇到記憶體不足的問題?
場景中有上百萬的多邊形時, 算圖應該如何設定?
要怎樣設定讓算圖變快?
什麼是raycasting? V-Ray是怎樣加速raycasting的?
什麼是BSP tree? 在V-Ray裡面又是長怎樣?
靜態Raycaster (Static Raycaster)與動態Raycaster (Dynamic Raycaster)兩者有什麼差異?
V-Ray怎麼處理虛擬記憶體(paging , swapping) ?
要怎樣把V-Ray切換到Dynamic Raycaster?
V-Ray bucket是什麼東西?
為什麼我們需要看V-Ray rendering log訊息?
要怎樣改變V-Ray算圖處理的優先順序?
當V-Ray在計算Light Cache的時候當機, 我該怎麼辦?
動態記憶體的限制(Dynamic Memory Limit)要怎樣計算出來?



V-Ray的當機問題
很多論壇都在討論對於很重的場景, 要怎樣用V-Ray算圖?
也就是說當缺乏記憶體的時候, 要怎樣進行算圖? 這也是3ds max與V-Ray當機最主要的原因.

為什麼會發生這種事? 是什麼造成了這個錯誤? 難道就不能用很簡單的辦法來解決嗎? 難道對於大型專案我們無可避免地要購買大量的記憶體? 要回答這問題, 我們先看看V-Ray如何使用記憶體, 以及什麼工具用來管理記憶體. 任何軟體, 記憶體管理與儲存資料的方式都很複雜, 至少對3D美術人員來說很複雜. 所以對我們來說, 也沒有必要去深入資料排列與資料定址的方式, 這些都是程式撰寫的領域, 為了要更容易管理RAM, 其實你只需要知道處理記憶體的基本概念就好了. 特別是, 大部分的使用者要面對的是軟體使用介面, V-Ray也不例外!


Raycasting---V-Ray算圖的第一步
在開始算圖之前, V-Ray會把場景的幾何體載入到記憶體裡面, 這會用在計算最終算圖上面, 這是所有算圖階段的初始步驟, 一旦你明白這個步驟對算圖器的重要性, 算圖的記憶體管理的重要性就不言可喻了!

一旦資料載入到記憶體中, V-Ray就可以開始算圖, 它會計算畫面每個像素, 探測場景的幾何體. 這探測的方式是利用一種特殊演算法, 稱為ray-casting, 基本上的概念就是場景攝影機會射出光線(rays), 也就是光線自攝影機射出去, 在場景中飛行, 直到碰到幾何體. 一旦每條光線跟場景幾何體的交錯確定了, V-Ray也就確認了幾何體在場景中的位置. 這也是收集基本資料與相關資訊為了下一個算圖步驟做準備.

沒有整理過的資料會有哪些缺點
單一個光線(ray) 與幾何體的交錯, 決定幾何體的屬性所耗費的時間並不長, 但是在計算相片等級寫實的圖片, 需要計算大量的光線. 例如HD影片解析度為1920X1080 會有兩百萬個像素, 這樣的數量會讓traycasting這個動作變成很耗費電腦資源的階段.

我們想像一下, 如果場景的幾何體是由一組的綠色樹葉所構成, 而raycasting演算法就好像一隻努力工作的螞蟻, 它想要從綠色樹葉中找到好吃的黃色樹葉, 這是比喻, 黃色樹葉象徵當raycasting的光線打擊到集合體所得需要的資料. 一開始的時候, 場景的幾何體會載入到記憶體, 以隨機的方式排列, 就好像所有的樹葉很混亂地堆成一堆. 這隻辛勤工作的螞蟻想要在大量的綠色樹葉中找到黃色樹葉, 要怎樣做呢? 它會一片一片樹葉來找, 從最接近牠的樹葉開始, 直到他找到黃色樹葉.


螞蟻會先查看第一片葉子是否為黃色, 接著看第二片葉子, 接著第三片…基本上要看完所有的葉子, 用這種方法一定可以找到黃色葉子, 但是也難保證黃色葉子不會是最後一片葉子. 在本例裡面, 為了要找一片黃色葉子, 可能要檢查一堆綠色葉子.

這很像我們未整理的場景幾何體資料一樣. Raycasting演算法會強迫場景幾何體排序, 然後檢查它們在場景單一點的屬性, 也就是跟光線交錯的位置. 這個方法太費時了, 為了在記憶體用這種方式找東西時在是很不合理!

BSP tree與方便找尋的資料結構
為了要促進raycasting決定場景幾何體屬性的速度, V-Ray 會把場景幾何體變成一種特殊的, 方便性的結構. V-Ray會把幾何體依照層級的結構放置於記憶體中, 這個結構稱為Binary Space Partitioning (BSP) tree. 這是一種很特殊的方法以二元樹狀結構, 來呈現大量資料. BSP的基本概念是把場景中所有的幾合體系分成兩個部分, 這樣會分成兩支, 在這個階段就有了根(root)與樹枝(tree). 在首次細分後, 又再經過第二次細分, 分之的點稱為樹枝的結點(Nodes of the tree).

場景幾何體的細分與每個分支的資料紀錄當達到限制值就會停止, 這會依照BSP tree的參數來決定, 這分支的結果稱為樹的葉子(Leaves of the tree). 這樣 V-Ray產生了整體場景幾何體的分支結構, 這對於搜尋場景特定區域的屬性來說是很棒的. 我們用找螞蟻葉子的比喻很清楚理說明了, 一開始的資料結構化對於資料的搜尋很有幫助.


如果我們不是把樹葉堆成一堆, 而是很仔細地用樹枝狀的方式來整理, 我們就可以很迅速地找到黃色的樹葉. 在這個故事裡面, 螞蟻, 可以避開不需要的分支, 直接就走向目的地, 這是因為它不需要查驗所有的樹葉. 相反地, 它幾乎可以直接找到到達黃色樹葉的路徑 .

根據這個原理, V-Ray把場景幾何體的資料結構化, 這樣又節省了我們寶貴的時間 即便是在這個看似不重要的步驟上面.

在這個階段的算圖原理很簡單: 載入, 結構化, 找到需要的屬性, 算圖.

既然我們知道這基本原理, 我們要進入下一步, 也就是如何渲染巨大場景.

靜態Raycaster與載入整個場景到記憶體裡面.

我們已經知道 開始算圖前一定要先把整個場景載入到記憶體, 上一章, 我們研究了樹狀結構.

但是, 前面所述, 還有一個關於算圖的問題, 只要安裝在你電腦的實體記憶體足夠的話, 算圖就會很順利. 事實上 V-Ray有兩種不同的raycasting演算法: 最簡單的一個叫做靜態((Static ) Raycaster, 它會一次把場景所有的幾何體載入進去. 想像一下, 如果場景有百萬個多邊形, 所以要把這些全部載入到記憶體會不會記憶體不足? 如果很不幸地, 記憶體不足, 就會發生很悲慘的事情----V-Ray當機.



因為發生重大錯誤所以軟體當機了, 因為可用的記憶體不足, 想要把所有的幾何體載入到記憶體變成不可能的事, 而用戶最後看到的訊息會是”Current Task: Buliding static raycast accelerator” 然後, 3ds max與V-Ray就一起當機了!


在我們的比喻裡面, 就好像V-Ray嘗試做出過兩的分支樹葉, 過重的樹造成倒塌 樹幹再也支撐不住了!

Dynamic Raycaster 與動態載入局部幾何體
不想要以增加實體記憶體的方式解決上述問題的唯一辦法是: 不要一次載入所有的場景等. 因此, 我們依序地載入部分場景, 只處理某段動畫算圖需要的幾何資料. 如你預期, V-Ray就有提供這種載入載入幾何體到記憶體的方法, 這種方法是動態(Dynamic)的Raycaster, 就是專為上述問題所設計的.

跟靜態的raycasting引擎不同, 動態raycaster允許你載入部分的幾何體. 動態的raycatser只載入部分的記憶體, 這個記憶體的量不超過指定的上限, 一旦載入的記憶體已經用在當前的算圖區域上面, 被佔據的記憶體就會清空, 然後載入其他部分的幾何體.

使用動態raycatser避免了記憶體不足的問題, 不光只是因為記憶體本身的限制, 動態raycaster知道怎樣利用作業系統的記憶體管理, 這表示即便是實體記憶體仍然不夠用的情況下, 作業系統還是能夠分配記憶體資源而成功地進行算圖, 特別是Winodws 會使用所謂的分頁(swapping)用來把無法存在實體記憶體的資料改存在硬碟裡.

雖然前面所提到動態幾何體載入的優點, 我們必須了解動態raycaster如果真的是萬用的方案, 那麼就不會發生使用靜態raycaster發生當機的問題了. 然而, V-Ray是以靜態raycaster作為預設值.

載入與卸載資料會耗費寶貴的時間, 就算我們設定了理想的RAM上限, 使用動態raycatser還是會很顯著地增加整體算圖時間, 而且如果還用到了分頁檔的話 那麼算圖時間會更多!

簡而言之, 這就是使用raycaster的記憶體問題. 既然我們了解了raycaster的原理, 那我們就來看看實際參數設定與管理技巧:

Binary Tree的參數設置

現在讓我們開始來看看V-Ray所提供的Raycaster 參數
前面三個參數描述了raycasting加速的結構, 也就是BSP tree. 這很抽象, 讓我們還看看每個參數吧!
Max tree depth 最大分支深度用來限制樹木分支的深度,它會指定場景空間的分支數目, 這個數值反映出從樹根到樹葉的最大樹葉數目. 這個數字越高, 樹就有越多分支.

Min leaf size 最小的樹葉大小限制了二元樹的結構, 讓樹葉的大小控制在一定大小, 這個參數可以阻止場景持續細分, 當達到最小樹葉大小的時候, 小的Min leaf數值不會限制樹木的分支,  所以二元樹會依照前面那個參數所定義的方式生長.

Face/level coef.決定了在單一個樹葉結點裡面的最大的幾何三角面數目, 這個參數月小, 就能產生越多分支的樹木, 很多的葉子. 我們知道 V-Ray會用BSP tree來組織化場景的幾何體, 加速raycasting的計算, 邏輯上樹的結構越,深 我們就需要越多的記憶體來儲存樹幹, 也就越能提供越快的算圖速度. 然而在這樣的加速狀況, 還是有個限制, 在超過某個閥值以後, 太多的細分就不合理, 因為過多的細分讓處理細分本身就過於困難,  raycasting演算法可以會因為花費過多的資源. 在巨大的BSP tree上面爬呀爬, 把原本加速的優勢給消耗掉了!

所以, BSP tree的最佳大小是什麼? 才能達到最高的raycasting速度?

答案並不是很令人鼓舞, 只有透過實驗才能知道最佳的 BSP tree參數. 並沒有那種適用於任何一種場景都通用的快速參數. 為了達到最佳的raycasting速度, 每個場景都需要個別設定BSP tree. 當對算靜態圖, 這些耗時的測試是完全沒有意義的, 因為這會花太多時間. 你應該會同意, 大概要花10倍的算圖時間, 才能找到最佳BSP設定, 實在是沒有意義!

但是BSP不單單只是展示了算圖引擎的能力, 這功能的主要目的還是在於動畫上面. 假設你要渲染有1000個frame的動畫, 我們花點時間來測試最佳的BSP參數就很有意義了! 就算你要算10-20次的最終算圖才能找到最佳參數, 而這個最佳參數可能可以讓每個frame增加20秒, 這樣的測試努力是有用的. 畢竟, 最佳後對於整體的動畫時間可以省下將近五小時! 對於靜態的算圖, 改變參數只有理論上的意義, 除非你希望讓記憶體損耗小一點, 把BSP tree改小, 以算圖時間增長為代價.

動態的記憶體限制是決定給動態dynamic caster用的記憶體上限, 這會定義每次動態raycaster載入部分幾何體所用的最高RAM的量. 字面上, 這個數字會再被電腦的執行緒所分割, 這個數值越低, 會顯著地降低raycaster的效能, 會導致載入與卸載幾何體的頻率. 除此之外, 小的數值會造成慢的翻頁檔的經常使用, 相反地, 數值越高可能會讓算圖器變慢, 對作業系統會比較吃重. 你可以把這個數值設定為實體記憶體的60-80%會達到較好的效能, 在使用V-Ray的時候謹記這個原則.

接下來, Default geometry parameter決定載入幾何體到記憶體的方法, 我們可以選取raycaster類型, 在談到default geometry選項之前, 我們應該先提一下, V-RayProxy與V-RayFur物件, 當你使用這類型的物件, 不管你是用怎樣的default geometry都沒有影響. 這些本來就是用動態raycaster來處理的, 會有這個選項主要原因是超多面的幾何體, 最好載入部分的模型, 避免程式當機.

靜態是最瑣碎的raycasting模式, 當我們選取靜態, 所有的場景資料會全部載入到記憶體, 在算圖之前. 動態是對預設幾何體的一種妥協模式, 動態raycaster 不會一次載入場景所有的物件, 它只會載入部分. dynamic memory limit數值決定了每次載入的模型最大量是多少. 自動是預設選項, 在這個模式 V-Ray會決定場景中的物件該用靜態或是用動態的raycaster計算會比較好. 這個決定會因為場景中特殊物件所決定, 跟多邊形與他的instance數目有關, 這是一個混合模式, 他會結合靜態與動態的raycatser運作.

如果我們比較不同類型的raycasters, 我們會發現動態的是最直接的, 但也是最慢的. raycaster 使用動態模式, 我們可以解決3ds max記憶體不足的問題, 但是 因為要花時間持續去載入, 填滿記憶體, 算圖時間就會很顯著地下降. 當使用靜態raycaster算圖, 只需花一次管理記憶體資源. 靜態模式最有生產力, 但也最不穩定. 如果所有的幾何體都能載入到記憶體, 算圖就可以很快, 然而, 我們如果場景幾何體很多, 會造成軟體當機的問題. 請回想一下前面樹木倒塌的比喻.

表面來看, 預設的幾何體設為自動, 算是萬用的模式, 建議使用這個預設參數.

Buckets的選項

這個選項設定V-Ray算圖時候的分割大小. 這個分割稱為bucket, 讓最終的算圖大小分割成很多小的區域. 你會在frame buffer看到bucket就是很多小方塊, 很迅速地移動, 最後把整個算圖畫面完成. 把最終算圖的畫面分割成很多小部分, 讓CPU不同的處理線程來處理不同的部分.

這樣, 原本是單一的計算被分割成很多小部分. 當每個bucket被渲染出來時, 會在frame buffer顯示結果, 這個結果好像拼圖一般, 最終會拼湊出整個畫面.

讓我們來看實際的bucket參數
x與y決定水平與垂直的大小.  這兩個數值預設大小是一樣的, 當你切換到region count模式, 那麼x y就代表切割數目 (而不是大小).

很顯然, 最終的影像分割成越多部分, 那麼V-Ray就會耗費越多資源在處理每個分割的邊界區域, 同時, 越小的分割也就可以讓每塊的算圖區域所需要的幾何體快取越小. 這是一個很棒的參數, 因為bucket, 就是動態raycaster載入到RAM的部分, 減小bucket很有用, 如果bucket高過了記憶體限制的話, 理論上越小的bucket會載入越小的幾何體, 可以避免作業系統使用到分頁檔. 優點與缺點, 很難做預測, 所以預設值設定為64x64.

Region sequence計算的順序, 是控制小方塊渲染的順序, 有六種模式: Top/bottom, Left/right, Checker, Spiral, Hilbert curve,與 Triangulation.

最有趣的模式是Triangulation, 用了這個模式以後, bucket會以不同的大小三角化,然後布滿整個render buffer. Triangulation最主要的功能是它會逐漸地布滿非常稠密的區域, 這對動態的raycaster很有用, 有了這樣的模式, 就比較有可能用在上一個bucket的幾何體, 能夠用在當前的bucket上面, 這樣可以節省電腦運算資源, 避免不必要的載入與卸載操作. 也就是這樣, 就算你很喜歡蛇行或是棋盤格的花樣, 不管怎樣還是採用V-Ray 它預設的Triangulation模式作為bucket 算圖的順序會比較好.

注意到如果你場景中有大量的動態幾何體, 例如displacement-mapped objects, V-RayProxy或V-RayFur, 因為Triangulation會以很穩定的模式走過最終算圖的影像, 所以在前一個bucket所載入的幾何體就可以給下一個bucket所使用, 其他種類的排序模是很容易由一個影像跳到另外一個, 對於載入動態影像十分不利!

Reverse sequence翻轉序列: 會反轉bucket計算的順序. 例如, 如果是Left/right模式, 他的算圖順序就會變成由右到左, 這不會影響到整個算圖過程, 但是有時候會很有用.

資訊統計註解 (Frame Stamp Statistics)
Frame stamp提供最終算圖的資訊, 有了這個功能, 我們可以在圖像上面添加各種技術資訊, 這資訊可以是: 當前的frame, CPU的型號, V-Ray的版本與最終算圖的解析度. 這功能有時候會很有用, 例如, 當你想要決定BSP tree的最佳尺寸, 啟動Frame Stamp, 也能讓你有機會對同事吹牛說你的電腦有多快. 當然啦, 這個功能對算圖本身是沒有幫助的.


V-Ray算圖的訊息 (Log)
接下來我們來探討V-Ray log. 這個功能很有用, 如果你勾選了V-Ray log, 在算圖的時候會開啟V-Ray messages.會顯示很有用的資訊, 例如警告, 錯誤與統計. V-Ray log對於用來處理分散式算圖是不可或缺的工具, V-Ray messages會顯出哪一台電腦在算圖, 哪一台是閒置狀態, 這樣你就可以知道在算圖初期有什麼問題可以避免掉.

V-Ray log還會把紀錄寫到文字檔裡面, 你可以在show window 選框指定路徑, 如果3ds max突然發生當機的話, 我們就可以找到這個文字檔, 看看錯誤訊息 以及找到它當機的原因. 數字表示你要顯示哪些資訊(1)表示險是錯誤訊息 (2)表示險是錯誤與警告 (3)表示險是錯誤, 警告與一般資訊 (4)表示告訴V-Ray顯示所有資訊. 建議你勾選顯示V-Ray log, 然後層級設定為 (3)

失去控制的GI Maps
大家要注意的是, 這篇教你們的, 是控制場景的幾何體資料, 跟GI Maps的資料在記憶體的管理無關. 這表示不管BSP tree尺寸是怎樣設定, 不管你是用哪種raycatser, 不管記憶體的上限設定, GI maps還是會全部載入到記憶體中, 需要多少記憶體空間它們就會占據多少.

在真實的狀況, 算圖器做完了所有的準備階段, 包括載入幾何體到記憶體, 甚至開始計算 GI Maps, 例如Light Cache 當在渲染部分的LC的時候, 算圖當機了!顯示大家都討厭的訊息”V-Ray exception error” 會發生這種原因是存在於記憶體的幾何體資料, 讓記憶體無法再儲存LC的資訊了. 很不幸地, 像這樣再計算GI的階段所發生的問題目前還沒有好的方法解決.

然而, 還是有些辦法的. 最簡單的就是降低GI maps的大小, 藉由降低最終算圖的品質, 另外還有一種妥協的辦法, 我們可以把影像的算圖分割成好幾的片段, 例如你可以用小塊的算圖區域來處理整塊算圖大小 (利用render region的功能)

結論
以上就是V-Ray的system settings裡面美術人員必須要知道的事情. 希望這個教學能夠幫助你解決當專案期限逼近的時候遇到的困難問題----3ds max突然當機. 現在你知道了V-Ray算圖系統的基本運作原理, 你就比較能管理大型場景, 不論你的電腦RAM有多少了!
祝算圖愉快, 有美麗的3D算圖效果!

[相關資訊]


No comments: