Anime Shading Plus
Show / Hide Table of Contents

📝 關於ASP中不同shader的效能

ASP/Character與ASP/Eye的Static Branching


ASP的character與eye shader均是forward rendering的shader,
並且開發過程中嚴謹的使用shader keyword來做功能的static branching。
舉例來說,一個使用ASP/Character的材質球,如果沒有使用rim lighting分類下的frensel rim light或者depth-based rim light,那該材質在runtime就絕對不會進行rim lighting的相關計算。同時像是貼圖property,只要沒有使用就不會有採樣的操作。

因此一個材質球啟用的功能越少,runtime的負擔就越小。

Texture Sampling Count(重要)


一般來說,在優化一個Shader時,我們希望能盡可能的減少每個frame中傳給GPU的貼圖數量,將skinned mesh的材質數量減少並且將不同材質球的貼圖打包唯一張atlas。
理論上,我們可以將不同部位的ramp map合併成一張ramp map atlas,並且利用另一張look up texture或者vertex color去控制採樣ramp map atlas的uv值(此種作法常見於一些手機遊戲-e.g 原神)
但這通常會需要配合不同的專案需求制訂嚴謹的製作流程與規則。ASP作為一個給不同專案使用的插件,為了保持使用上的彈性,無法強制使用者走特定的流程 (唯一的例外是PBR貼圖的通道)。
在每個材質球都使用獨立的貼圖的情況下,換來的就是有較高的bandwidth overhead,這對手機或VR/Switch等平台的GPU較不友善,因此,ASP預設的target一直都會僅限於PC。

💡 實際上根據專案需求時做合併貼圖的邏輯並不複雜,對有餘力且目標是手機等平台的團隊來說,ASP的shader仍然可以作為一個卡通渲染的基底並加以自行改造與擴充。

ASP Shadow Map的效能


單獨渲染人物的ASP Shadow Map可以為最多4層的cascade shadow ma。
Cascade shadow map - 可以想像是陰影的LOD,將shadow map切為多份較小的tile後,每個tile由不同的陰影距離去渲染。
較高的cascade count可以在維持小的shadow map resoluttion的同時,針對不同距離都得到較一致的陰影品質。

一個2層cascsade的shadow map

一個2層cascsade的shadow map

但每多一層cascade就會多一次draw call,四層cascade在worst case的情況下會需要渲染角色至shadow map4次。而人物用mesh除了面數通常較高外,skinned mesh本身在CPU端有很高的overhead(計算骨架是很昂貴的操作),使用多層cascade容易造成CPU bound。

💡 請記得,遊戲專案中渲染人物常用的skinned mesh renderer本身就是計算較為昂貴的物件。

情境 建議設置
CPU-bound但bandwidth足夠 降低Cascade Count,盡量cascacde count為1或2,可以使用較大的shadow map resolution(2048x2048)。
Bandwidth-bound 降低shadow map resolution
追求效能 使用1層cascade,並且降低shadow map resolution,同時降低clip distance提高在近距離時的陰影品質。使用高shadow fade ratio使相機遠離時能淡出陰影,並且在遠離時切換為假的blob shadow(目前並不包含在ASP中)

Mesh Outline/ Depth Offset Shadow


Mesh-based的outline pass與Depth Offset Shadow pass如同一般的draw call(當然,這些pass的per-pixel的計算量非常低),因此這些pass的執行時間與要繪製的物體總數/複雜度程正相關。

因此,請多利用Rendering Layer Mask來控制會被渲染至這些pass的物件,最大限度地降低繪製進這些pass的renderer數。

後處理Shader(螢幕空間輪廓線、Tone Mapping)


在RTX 3060 laptop上,這是ASP的後處理pass與Unity的SSAO pass的效能比較。

後處理效果 執行時間
Unity SSAO 0.6ms~0.95ms
ASP Screen Space Outline depend on character pixel coverage on screen usually 0.4ms~0.5ms , worst case 0.95ms
ASP ToneMapping 0.2ms

運算螢幕空間輪廓線時,為了最大化可偵測到的邊緣細節,我們需要對_CameraDepthTexture與_CameraNormalTexture進行多次的採樣,同時需要採樣Material Pass的RT。
ASP邊緣偵測時的採樣次數大約是Sobel operator的一半以下。但得到的細節並不會比使用sobel operator少。
另外,為了避免不必要的採樣,螢幕空間輪廓線shader會先判斷當前pixel是否為人物的pixel,如果不是的話便會跳過後續的計算以節省效能。
換句話說 - 人物佔據畫面的比例越少、省下的效能就越多。

另外在screen space outline的volume override中,有提供對輪廓線單獨進行一次FXAA - 已獲得更高品輪廓線的選項。FXAA反鋸齒在現代的PC來說已經是非常便宜的計算,因此是建議啟用的。

Profiling結果


以下是RTX 3060 laptop 在9個人物(36個Skinned mesh renderer)場景的nsight frame capture

Image

Image

Project Setting : Script Backend - Mono

Graphics API : DX 12

GPU Skinning : ON

Graphics Jobs : OFF

後處理效果 所佔據的Frame Time
Unity SSAO 0.61ms
ASP Shadow Map(Character-Only) 0.07ms
Draw OpaquesObjects 0.45ms
ASP Tone Map Pass 0.27ms
ASP Screen Space Outline 0.61ms
Render Post Processing(Bloom..etc) 0.35ms
Total Frame Time 3.37ms (~270FPS)

Draw OpaquesObjects會被mesh的數量與複雜度、面數、以及draw call數量來影響執行的時間。

如果忽略mesh的複雜度的影響,則ASP Screen Space Outline會是ASP的shader中較為昂貴的,Outline + ToneMapping在3060 laptop下大約需要合計0.8~1ms。

  • Edit this page
In this article
Back to top Generated by DocFX