渲染優化01
阿新 • • 發佈:2018-10-04
ppi 不同 出了 head 系列 normal process man 組件
https://unity3d.com/cn/learn/tutorials/temas/performance-optimization/optimizing-graphics-rendering-unity-games (官方原文鏈接)
遊戲中的圖形渲染優化
- 介紹:
- 渲染簡介:
- 減少batches的數量並且/或者讓更多的物體使用相同的渲染狀態,在多數情況下,是能減少SetPass call數量的
- 減少SetPass call的數量,在多數情況下,會提高CPU性能
- 簡單地減少場景中可見物體的數量是一個非常有效的方法。比如,如果我們渲染大量的角色模型,那麽可以試驗一下少量角色模型的情況。如果場景表現有所提升,這將是更便捷的方案,而不是復雜的技術了。
- 通過攝像機組件的Far Clip Plane屬性降低攝像機的繪制距離。攝像機的可視距離範圍。如果希望遠處的物體看不見,可以嘗試使用這個:
- 基於距離,為了更多細粒度的隱藏物體的方式,可以使用攝像機的Layer Cull Distances屬性,為不同層級的物體提供自定義的裁剪距離,如果有很多前景細節裝飾,那麽這個方式是很有效的;我們能夠在更加短的距離上隱藏這些細節。
- occlusion culling(遮擋裁剪,遮擋剔除)是使那些被其他物體遮擋的物體不被渲染出來的技術。比如場景中有一個比較大的物體,這個物體後面有其他的物體,那麽就可以使用occlusion culling(遮擋剔除)。Unity的遮擋剔除技術(occlusion culling)並不是適合所有的場景,它會造成一定的CPU開銷並且設置起來也比較復雜,但在某些場景中它是可以提高性能的。這有一篇學習occlusion culling的博客:
- Unity中的動態光照是非常復雜的課題,所以深入探討這個話題已經超出了本篇文章的範疇。這裏提供兩篇學習文章(https://unity3d.com/cn/learn/tutorials/topics/graphics/introduction-lighting-and-rendering(動態光照介紹),https://docs.unity3d.com/Manual/LightPerformance.html?_ga=2.162255028.925366423.1538040429-1156207016.1532919959 (詳解普通光照優化))
- 動態光照是非常消耗性能的,當遊戲場景存在一些不動的物體:比如,風景,我們可以使用一個叫做baking(烘焙)的技術去預先計算光照,這樣在實時光照時就不會再計算了,學習這個技術請移步:https://unity3d.com/cn/learn/tutorials/topics/graphics/lighting-overview?playlist=17102 而這篇文章:https://docs.unity3d.com/Manual/GIIntro.html?_ga=2.69613336.925366423.1538040429-1156207016.1532919959 詳細介紹了baked lighting (烘焙光源)
- 如果想要使用實時陰影,這是能提高性能的好去處 。這篇文章 https://docs.unity3d.com/Manual/DirLightShadows.html?_ga=2.167572022.925366423.1538040429-1156207016.1532919959 指引我們在Quality Settings如何調整shadow屬性並且告訴我們這些是如何影響性能的。比如,使用Shadow Distance屬性來確定只有近處物體會計算陰影。
- Reflection propes(反射探頭)能夠生成真實反射但這也是非常消耗性能的(增加batches)。應該盡量少的使用的反射,並且使用時盡可能的去優化。這篇文章https://docs.unity3d.com/Manual/RefProbePerformance.html?_ga=2.131305607.925366423.1538040429-1156207016.1532919959 (反射探頭優化)
- 相同的材質的相同的實例共享
- 材質設置相同(比如texture,shader,shader系數)
- Static batching(靜態批處理技術)能使Unity批處理近處且不動的符合條件的物體。比如,一堆相同的物體(比如巖石)就可以使用靜態批處理技術進行優化。這篇文章:https://docs.unity3d.com/Manual/DrawCallBatching.html?_ga=2.102928520.925366423.1538040429-1156207016.1532919959 介紹了靜態批處理設置的用法說明。靜態批處理會造成較大的內存使用,所以在分析遊戲性能時不能忘了分析這個
- 動態批處理是另一個能批處理那些符合條件的物體的技術,不論這些物體是否會動。使用這個技術會有一些限制條件。這些限制會被列舉出來,但與用法說明分開。這篇文章https://docs.unity3d.com/Manual/DrawCallBatching.html?_ga=2.94609172.925366423.1538040429-1156207016.1532919959。 動態批處理會影響到CPU使用量,並且它能節省的時間比開銷的時間更多。所以謹慎使用
- 批處理Unity UI元素會有些小困難,因為會被UI布局所影響。文章
- 就裁剪本身而言是不太消耗性能的,但是刪減掉不必要的裁剪也是會有助於性能的提升的。對於場景中所有激活的物體,包括那些不被渲染的層上的物體,都會有逐對象逐相機的日常開銷(per-object-per-camera overhead).我們可以通過disable相機並且deactivate或disable那些當前沒有使用的渲染器來減少開銷。
- 批處理能夠很大程度上提升發送指令的速度(CPU發送給GPU的指令的速度),但有時候會在別的地方增加一些多余的開銷。如果批處理操作促成了遊戲的CPU bound,那麽我們就應該限制手動的或自動的批處理操作了。
- 我們應該考慮是否每一個物體(當前已經用了SkinnedMeshRenderer組件的)都需要使用SkinnedMeshRenderer組件,有個情況就是,我們導入了一個使用了SkinnedMeshRenderer組件模型,但我們沒有給它動畫,像這樣的話,把SkinnedMeshRenderer組件替換成MeshRenderer組件是可以提升性能的。當我們導入一個模型時,如果在“the model‘s import Settings”中選擇了不導入動畫的話,這個模型就會使用MeshRenderer組件,而不是SkinnedMeshRenderer組件。
- 如果只是在某些時候需要使用動畫(比如,在遊戲啟動時或僅僅在離攝像機一定距離時),我們可以換成網格細節更少的版本或者使用MeshRenderer。SkinnedMeshRenderer組件有一個BakeMesh功能,這個功能能生成匹配姿勢的網格, 能使不同網格或不同渲染器之間進行交換但卻不會造成任何視覺上的物體改變
- https://docs.unity3d.com/Manual/ModelingOptimizedCharacters.html?_ga=2.87438096.925366423.1538040429-1156207016.1532919959 這篇文章給出了一些優化那些使用了蒙皮網格的動畫角色的建議。
- https://docs.unity3d.com/Manual/class-SkinnedMeshRenderer.html?_ga=2.160772661.925366423.1538040429-1156207016.1532919959 這篇文章介紹SkinnedMeshRenderer,包括了怎麽去調整組件屬性等來提升性能。另外還有一些使用建議,需要記住,蒙皮網格的開銷是逐頂點增加的;減少模型頂點才能減少工作量。
- 在某些平臺上,蒙皮會被GPU處理,而不是CPU,如果GPU有足夠的能力,這樣的選擇是具有實驗研究價值的。我們可以在Player Setting中為當前平臺和目標設備啟用GPU skinning。
- 進行性能分析並紀錄好GPU時間
- 在Player Setting中降低顯示分辨率
- 再次分析遊戲性能,如果性能有所提升,那麽就可以認為是fill rate造成GPU bound 的
- 片元著色器是shader定義的一段代碼,它告訴GPU應該如何繪制每一個像素,GPU會為每一個需要被繪制的像素執行這部分代碼,所以如果這段代碼是低效的就會很容易增加性能開銷。復雜的片元著色器是造成fill rate問題的非常常見的原因
- 過渡繪制是指相同的像素被繪制了多次。這種情況是在一些物體在另一些物體上面繪制時發生的,並且這個很容易造成fill rate問題。為了搞明白過渡繪制,就要弄清楚Unity繪制場景物體的順序。物體的shader決定了它的繪制順序,通常是通過指定的渲染隊列。Unity利用這些信息嚴謹繪制物體,文章:https://docs.unity3d.com/Manual/SL-SubShaderTags.html?_ga=2.160756277.925366423.1538040429-1156207016.1532919959 另外,在繪制前,不同渲染隊的物體會使用不同的排序方式。比如,Geometry隊列下,Unity從前往後對物體進行排序,以減少過渡繪制。Transparent隊列下,是從後往前來實現想要的視覺效果的。Transparent隊列下的從後往前的排序是會增加過渡繪制的。過渡繪制是非常復雜的研究課題,沒有唯一的方法解決這個問題,但減少重疊物體的數量是關鍵點,因為Unity不能自動對這些物體排序。在Unity Scene窗口可以很好的研究這個問題,Draw Mode(繪制模式)能讓我們看到場景中的過渡繪制,進而確定怎麽去減少(過渡繪制),造成過渡繪制最常見的罪魁禍首是透明材質(transparent material) 、沒有優化過的粒子,重疊的UI元素,所以優化或減少這些是可行的。https://unity3d.com/cn/learn/tutorials/topics/best-practices/fill-rate-canvases-and-input?playlist=30089 (關於UI和overdraw指導)
- 圖片效果也是很容易造成fill rate問題的,尤其是當我們使用多種圖片效果時。如果遊戲使用了圖片效果並且造成了fill rate問題的話,我們應該去調整設置或使用更加優化的圖片效果(比如高光(優化過的)),如果在相同的相機中使用多種圖片效果,這將造成多次shader pass。在這種情況下,合並這些圖片效果的shader代碼成一個獨立的pass塊是有益的。比如Unity的延遲處理堆棧:https://github.com/Unity-Technologies/PostProcessing/wiki 如果經過優化後的圖片效果還是會有fill rate問題,那麽就要考慮不用圖片效果了,尤其是在低端的設備上。
- 對遊戲進行性能分析並且紀錄GPU消耗時間
- 在Quality Setting中設置好目標平臺的目標質量,降低紋理質量
- 重復第一個步驟,如果性能提升,那麽就能確定是內存帶寬的問題
- 紋理壓縮技術:能夠紋理的磁盤存儲大小和內存大小。如果內存帶寬在我們遊戲中會造成性能問題,使用紋理壓縮技術是可以提升性能的。在Unity中有多種紋理壓縮技術,每一種都有單獨的設置界面。通常來說,某些紋理壓縮是無論何時都是會被用到的,然而,一個試驗和錯誤能夠讓我們找到每一個紋理性能最好的最佳設置。請看這篇文章:https://docs.unity3d.com/Manual/class-TextureImporter.html?_ga=2.191165986.925366423.1538040429-1156207016.1532919959
- 紋理映射(MipMaps)是優化方案中效果沒那麽好的技術,在Unity中可以用在遠處物體上。如果場景中有跟攝像機距離比較遠的物體,使用mipmaps能夠緩解內存帶寬帶來的問題。The MipMaps Draw Mode(https://docs.unity3d.com/Manual/ViewModes.html?_ga=2.103665800.925366423.1538040429-1156207016.1532919959)(Scene Mode下),能夠看到使用MipMaps後的好處,還有這篇文章:https://docs.unity3d.com/Manual/class-TextureImporter.html?_ga=2.199507494.925366423.1538040429-1156207016.1532919959
- 首先,要減少那些不必要的復雜網格。如果使用了那些在遊戲中看不見的網格或因為生成時錯誤的有大量頂點的無效網格,這會讓GPU做很多無用功。降低頂點處理的開銷的最簡單的方法就是在我們的3D項目中生成更少頂點的網格
- normal mapping(法線映射)技術是指紋理用在了可以生成龐大的復雜幾何結構幻覺的網格上的技術。一些GPU的性能開銷使用這個技術是可以提升性能的。https://docs.unity3d.com/Manual/StandardShaderMaterialParameterNormalMap.html?_ga=2.123024131.925366423.1538040429-1156207016.1532919959, 這篇文章指導我們使用normal mapping(紋理映射)來在網格上模仿復雜的幾何結構。
- 如果網格中沒有使用紋理映射技術,一般會在網格的import settings中將vertex tangents(頂點切線)禁用掉。這種數據上的削減會設置到每一個頂點上
- LOD(Level Of Detail 細節層次渲染)是一種可以降低遠離攝像機的網格的復雜度的優化技術。降低需要渲染的頂點數量且保證不失真。https://docs.unity3d.com/Manual/class-LODGroup.html?_ga=2.200163238.925366423.1538040429-1156207016.1532919959
- 頂點著色器(shader代碼塊,告訴GPU如何繪制每一個頂點),如果遊戲因為頂點處理受限,那麽降低頂點著色器的復雜度是可以提升性能的
渲染優化01