天天看點

三維場景的渲染優化

一  如何進行有效的性能評測

   對于任何一個3D應用程式來說,追求場景畫面真實感是一個無止盡的目标,其結果就是讓我們的場景越來越複雜,模型更加精細,這必然給圖形硬體帶來極大的負荷以緻于無法達到實時繪制幀率。是以,渲染優化是必不可少的。在渲染優化之前,我們需要對應用程式性能進行系統的評測,找出瓶頸,對症下藥。對于3D應用程式來說,影響性能的十分多,同時不同的硬體配置條件下,瓶徑也會有所不同。是以,對應用程式進行有效的性能評測,不僅需要對整個渲染管線原理有深入地了解,此外借助一些評測工具能讓我們的工作事倍功半。

  我們知道渲染流水線的速度是由最慢的階段決定首先,是以對一個3D應用程式進行評測,首先要分析影響渲染性能的瓶頸是在CPU端還是GPU端,由此來絕對我們優化的對象。由于目前的圖形加速硬體都具有強大的,這個瓶徑往往出現在CPU端,我們可以通過一些工具獲得這個資訊,如Nvidia的NVPerfHUD。在評測選項中,我們可以檢視CPU和GPU繁忙度這項,當CPU繁忙度是100%時,GPU還不是時,我們知道性能的瓶頸在CPU端,我們必須CPU端的操作,同時盡量的“喂飽”GPU,把一些費事的計算移值到GPU上,例如硬體骨骼蒙皮。當GPU端是瓶頸時,說明GPU超荷負載,有可能是因為有過多的渲染填充,也就是多邊形數量太多(目前強大的GPU使得這種情況并不多見。

  CPU上的瓶頸産生有兩個方面,一是因為複雜AI計算或低效的代碼,二是由于不好的渲染批處理或資源管理。對于第一種情況,我們可以利用VTurn這類的工具,把應用程式中所有函數調用時間從大到小的排列出來,我們就很容易知道問題所在。對第二種情況來說,同樣利用NVPerfHUD,我們可以檢視每幀的DP數目,看看批的數量是否過多(有一個具體的換算公式),檢視紋理記憶體的數目,是否消耗了過多的顯存。利用這些工具,我們基本上能夠定位應用程式的瓶頸。在應用程式内部,編寫一個内嵌的profiler功能,能更加便利的進行評測,此外利用Lua這樣的腳本程式,讓我們運作時調試,也能提高評測的效率。

二 靜态場景優化

        靜态場景包括了地形、植被、建築物等一般不改變位置的實體集合,對它的優化是場景優化中最重主要的内容。本文就靜态場景優化的常見問題進行了探讨。

1 批的優化

        批是場景優化中的最重要的概念之一,它指的是一次渲染調用(DP),批的尺寸是這次渲染調用所能渲染的多邊形數量。每個批的調用都會消耗一定的CPU時間,對于顯示卡來說,一個批裡的多邊形數量遠達不到最大繪制數量。是以盡可能将更多的多邊形放在一個批裡渲染,以此來減少批的數目,最終降低CPU時間,是批的優化基本原則。然而事情往往不盡如人意,有些情況下原有的批會被打破,造成額外的開銷,如紋理的改變或不同的矩陣狀态。針對這些問題,我們可以采用一些方法來盡量避免它,已達到批尺寸的最大化。

(1)合并多個小紋理為一張大紋理     在某個場景中,地面上有十多種不同的植被,它們除了紋理不同外,渲染狀态都是一樣。我們就可以把它們的紋理打包成一個大紋理,再為每個植被模型指定UV,這樣我們就可以用一個渲染調用來渲染所有的物體,批的數量就從十多個降為一個。這種方法比較适合對紋理精度要求不高,面數不會太多的物體。

(2)利用頂點shader 來統一不同矩陣的情況   即使場景中的所有物體材質都一樣,如果它們的矩陣狀态不同(特别是場景圖管理的引擎),也會打碎原有的批。利用頂點shader技術可以避免這種情況,因為可以把要乘的變換矩陣通過常量寄存器傳到shader程式中,這樣統一了物體的矩陣狀态,可以放在一個批裡渲染。

2 渲染狀态管理

        渲染狀态是用來控制渲染器的渲染行為,在D3D中是setRenderState,通過改變渲染狀态,我們可以設定紋理狀态、深度寫入等等。改變渲染狀态對顯示卡來說,是個比較耗時的工作,因為顯示卡執行API必須嚴格按照渲染路徑,當渲染狀态變化時,顯示卡就必須執行浮點運算來改變渲染路徑,是以給CPU和GPU帶來時間消耗(CPU必須等待),渲染狀态變化越大,所要進行的浮點運算越多。是以将渲染狀态進行有效的管理,盡可能 減少其變化,對渲染性能影響巨大。(新六代的顯示卡Geforce8系列中将一些常見的狀态參數集存儲在顯示卡核心中,當渲染狀态狀态發生變化,可以直接讀取儲存的參數集,以消除不必要的開銷)。絕大部分的3D引擎都會按照渲染狀态對PASS進行分組渲染。

3 LOD

    LOD這個已經被人讨論爛掉的技術我就不多廢話了,簡單談談一些實際應用。地形的LOD我就不多說了,方法太多了,不過感覺目前情況下最實用的還是連鎖分片的方法。對于模型LOD,自動減面的算法,如VDPM(漸近網格子)并不少見,但是效果都很一般。正常的做法還是讓美工做低模進行替換,對于複雜場景來說,模型LOD的效果還是比較明顯的。材質LOD就需要一些技巧,例如可以将霧後的物體,包括地形等統一成一種材質,采用霧的顔色,這樣就統一了渲染狀态,至于是否要打包成一個DP就要看具體情況了(這個統一的材質最好把光照影響關掉,這也是比較費時的)。至于角色模型的LOD和普通模型LOD相類似,低模減少了頂點數,自然減少了蒙皮計算量。個人認為骨骼LOD不是特别的必要,看具體的情況。

4 場景管理的優化

       場景管理的優化包括場景分割,可見性剔除等,有很多的參考文章,這裡就不多說了,談些個人的心得。現在的室外場景一般采用quadtree或octree,當我們在性能評測時發現周遊樹的過程比較慢時,有可能有兩個原因。一是樹的深度設定的不合理,我們可以很容易尋找到一個最佳的深度。另一個原因可能是我們為太多數量 衆多,但體積很小的物體配置設定了結點,造成結點數量的備援。解決方法是把這些小物體劃分到他們所在的大的結點中。

        可見性剔除是最常見優化方法,我們常用的是視錐裁減,這也是非常有效的。視錐裁減也是許多優化方法,這裡就不詳說了。遮擋裁減也是經常被用到的方法,常見的有地平線裁減。但是在有些情況下,遮擋裁減的效果并不明顯,如當CPU使用率已經是100%時,CPU端是瓶頸,這時進行遮擋裁減計算消耗CPU時間,效果就不明顯。但是有些情況下利用一些預生成資訊的方法,降低遮擋裁減計算的複雜度,提高遮擋裁減計算的效率,對場景性能會一定的改善。

http://blog.csdn.net/rhett_graphic/archive/2007/07/08/1682805.aspx

繼續閱讀