Unity開發怎麼優化大量物體的物理碰撞而產生的FPS等參數急劇下降?

如題。

unity新手一枚,碩士在讀。利用Unity做礦業演示系統,面對爆破工作,動不動就要設計多達2、3千塊的碎石(帶collider)爆破崩落模擬,還要模擬將碎石崩落後與狹窄斷面等的碰撞,更甚還要模擬數以萬計的礦石堆積,然後從一個小口放出的效果。

以上情況在測試時都會出現FPS降至2以下,甚至卡死的情況,(本人電腦配置為I7CPU,顯卡麗台K620,20+內存,)現在糾結是電腦配置有待提高還是細節優化不佳。已經在代碼層和場景構建中進行了相應的優化(比如:去除不必要的碰撞檢測,將一些物體設置為static,)

誠請各位大神指點如下:

1,對於我所說的大量帶有collider的物體碰撞模擬,或者Unity的強勢開發,需要一台多好的電腦配置才能遊刃有餘。

2,大量碰撞體場景的優化需要做哪些工作。

3,怎麼利用shader實現一個類似武器漸顯的效果。(這裡的漸顯不是透明度的整體變化,而是物體按照某軸逐漸生成,從部分到整體的效果。)

以上三個問題不一定全答,各位大神能者多勞,提前謝過。

4-21補充

在@呦呦呦佑子的提示下利用3D印表機效果基本解決了物體漸顯的問題。在此表示感謝。

筆芯。

其他答主的的建議還有待檢測,檢測有效果會及時更新。

對熱情回答的朋友表示感謝。筆芯。


可嘗試

  1. 盡量使用較簡單的碰撞形狀,通常耗時 Sphere &< Capsule &< Box &< Convex;
  2. 降低碰撞求解的迭代次數 Physics.defaultSolverIterations / Rigidbody.solverIterations,但會降低模擬準確度;
  3. 減低剛體休眠閾值 Physics.sleepThreshold,令減速中的剛體儘早進入休眠狀態。

如果只是演示,不一定要全實時進行。可以設置參數,然後以固定幀率進行模擬,模擬中儲存每幀結果,最後才用那些模擬結果來實時渲染整個過程。這樣做渲染時可改變攝像頭設置,用不同視覺觀看結果,這種程度的互動可能對演示用途來說已經足夠。


那樣大量的場景物件模擬進行本身就是很重的。所以有這個 APEX Destruction,所有模擬在一個物件內部進行。但是很不幸並沒有集成到 Unity。不過還有 Unreal:APEX。

And: [GamingBolt] Nvidia demos Real-Time Massive Destruction @ GDC 2013


1,對於我所說的大量帶有collider的物體碰撞模擬,或者Unity的強勢開發,需要一台多好的電腦配置才能遊刃有餘。

因為物理引擎本身就是極其耗計算量的東西。你既然對物理過程有這麼高的要求,為啥不用Nvidia的PhysX?這個可是GPU加速的,計算效率比其它物理引擎高到不知哪裡去了。

2,大量碰撞體場景的優化需要做哪些工作。

如果你真的需要實時計算碰撞和物理過程,那麼這方面的優化不是你能做的。運動積分、碰撞檢測、穩定支撐、能量穩定化,每一個展開都是遠古巨坑。哪怕僅僅是不可破壞的剛體物理,寫一個行為正確穩定的實現就已經很難了。

你唯一能做的優化,大概就是:

  • 想辦法不用真實的物理碰撞過程,而是用一些預計算的假的東西。
  • 用簡單的規則形狀(比如球)碰撞體代替多邊形碰撞體。


在可以計算physics的3d軟體里(比如blender)用fracturebake physics,再導出到unity里去。

blender自帶的一個fracture modifier:Using the Cell Fracture Feature in Blender to Create Advanced Dynamics

然後貌似有個可以把fps保持在你想要的數字的命令:

void Awake() {
Application.targetFrameRate = 300;
}

鏈接:

Application.targetFrameRate


自己從頭到尾寫一套碰撞吧,極大數量的碰撞使用compute shader來做。

特定的崩塌效果可以在3dsmax或者maya裡面進行物理運算,最後導出為頂點緩存動畫來做。


physx幫助文檔有說明。根據物理實體的類型進行sleep或者註銷。比如rigdoll就需要sleep。


謝邀,unity物理用的是nvdia的physx庫,這方面碰撞非常費的是MeshCollider。與BoxCollider跟 CapsuleCollider之類相比 , 差距非常大. 如果題主使用的是這種Collider可以考慮用其他Collider模擬,也可以參考一些破碎插件, 比如:Fracturing Destruction,2-3K在pc上還是能很好支撐的


unity用的是nvidia的physx,但只是cpu端的,沒有gpu加速,而且physx的gpu加速本身局限也很大

其他答主提到的compute shader和physx的gpu加速差不多只能做一些相對簡單的物理粒子模擬,在題主提到的如大量石子堆疊漏口的應用場景涉及比較複雜的力傳導,可能很難模擬得比較真實。

milo大神提的前幾個方法可以先試試看,做到實時比較困難。可以考慮用另一個線程用physx模擬,unity只作為一個顯式端對模擬結果插值。然後題主的應用場景可能每幀重建static aabb tree比直接用dynamic的更高效一些,可以嘗試一下


先用簡單的碰撞形狀,性能還是不夠的話用compute shader自己寫碰撞,應該難度還好


用一個灰度圖,在shader里根據閾值和灰度圖控制透明度


如果可以的話可以用粒子效果試試


物理碰撞的話真的很難受,這個回調會耗費很多內存,我們做的時候能不用物理的回調就盡量不用,像題主這種模擬模擬,我覺得物理是避免不了了,不過優化的方法是有的

用插件可以稍微減輕一點負擔,畢竟是經過很多人的檢驗了,有個模擬物理破碎效果的插件,我記得可以處理很多碎石塊的碰撞,名字是什麼忘掉了,百度unity破碎模擬插件大概會有這個插件,蠻牛上也有下載的。

有個笨方法,一旦出現大批量模擬的時候,暫停程序,但是物理不要停,畫面靜止,告訴用戶正在模擬。。。然後等計算完成就返回,繼續程序,這樣有點投機取巧不過也是種解決辦法

推薦還是插件

你說的漸隱效果,你去遊戲蠻牛上搜索,3D印表機效果就好了


如果只是在pc上,那可以用compute shader


請用unreal engine


推薦閱讀:

一個重新排列的演算法,如何計算每種排列的概率?
Unity遊戲編程中如何避免runtime動態alloc內存?
如何在Unity中預覽尋路的結果?
如何在Unity中對程序進行 Android 真機斷點調試?
unity 3d 中如何實現以物體的表面作為播放視頻的位置,比如在牆面播放視頻?

TAG:Unity遊戲引擎 | 爆破工程 | shader |