Unity&UE4屠龍術 - shader單步調(diào)試
首先表達一下個人對單步調(diào)試shader的看法。如果能單步調(diào)試shader,那自然是很強大,但是很多同學其實是并不需要的,因此,個人將shader單步調(diào)試稱為屠龍術。就是因為有屠龍(開發(fā)分析復雜shader)的需求的場景實在的非常少。
要說最強大,也是個人最習慣用的幀調(diào)試器,那就是renderdoc。renderdoc非常強大易用,以至于主流游戲引擎比如Unreal Engine 4 和 unity都提供了對renderdoc的內(nèi)建支持。renderdoc還有一個重要功能,就是提供了HLSL單步調(diào)試的能力。這次,我就要分享一下如何使用renderdoc的HLSL調(diào)試功能,來調(diào)試unity和UE的shader。
renderdoc 調(diào)試 unity shaderlab
前面已經(jīng)提到renderdoc支持調(diào)試HLSL,unity shaderlab使用的表面上是CG,實質(zhì)上是HLSL,所以當然可以用renderdoc單步調(diào)試unity shaderlab。
雖然unity也內(nèi)置了幀分析器,但是感覺還是不夠強大,除了replay功能之外缺失還是太多。
開啟 Unity 的 shader 調(diào)試整體還是非常簡單的,首先,在shader文件的 CGPROGRAM
塊中鍵入:
#pragma enable_d3d11_debug_symbols
這步的目的是讓 HLSL 編譯后保存調(diào)試符號,且跳過HLSL的編譯器優(yōu)化。

接下來在unity中啟用renderdoc支持,首先要在game窗口上右鍵,選擇 load renderdoc

之后再game窗口右上角可以看見renderdoc的圖標

點擊圖標完成抓幀,其中Camera.Render是game窗口的內(nèi)容

定位到具體的drawCall,如果發(fā)現(xiàn)texture output上下顛倒可以使用 Flip the texture in the Y axis。

UE4 以 dx 的窗口系為標準,所以 openGL 模式下上下顛倒。Unity則相反,以 openGL 窗口為標準,在 DX 下會上下顛倒。
用鼠標右鍵在 Texture Viewer 的 Output 中定位到要調(diào)試的像素,

然后點擊 Pixel Context 中的 debug 按鈕即可開始愉快的單步調(diào)試

renderdoc 調(diào)試 UE4 shader
相比Unity,相信有調(diào)試UE4 shader需求的同學應該少了一大半,不過為了完整性,還是記錄一下。
首先編輯 引擎目錄 下的 Config/ConsoleVariable.ini
文件。

仔細閱讀注釋說明,保留HLSL調(diào)試信息并關閉HLSL編譯器優(yōu)化。

之后打開UE4內(nèi)置的 renderdoc 插件。在 Edit -> Plugins 的內(nèi)置插件(Built-in)中搜索 renderdoc 插件。

開啟后重啟并編譯插件,之后可以在Editor viewer的右上角發(fā)現(xiàn)renderdoc的圖標。

點擊該圖標,即可完成抓幀。在Event brower中定位到需要分析的drawCall。

在tone mapping之前顏色偏暗看不清,可以重新映射顏色范圍。

用鼠標右鍵在 Texture Viewer 的 Output 中定位到要調(diào)試的像素,然后點擊 Pixel Context 中的 debug 按鈕即可開始調(diào)試(請務必確保該 drawcall 影響該 pixel,否則還是會顯示該pixel的pixel history)

之后即可開始單步調(diào)試HLSL。調(diào)試非常方便,不僅可以step forward,還可以step backward。并且存在超方便的功能run to cursor,只要鼠標定位到要執(zhí)行到的行數(shù)即可,連斷點都可以不打。雙擊寄存器可以在變量(Variables面板中高亮變量),當然懸停也可以顯示變量值。

renderdoc 的一些小技巧
其實不僅可以調(diào)試,還可以實時修改 shader,之后刷新就能看到效果。比如我把繪制人物的shader改為直接顯示紅色。


dx11(sm5)下默認使用延遲渲染,OutTarget0是color attachment
人物材質(zhì)被修改后的效果可以在Texture viewer中查看。這個功能很便于開發(fā)shader,避免反復編譯/重啟游戲浪費時間。

如果要快速尋找需要 debug 的 pixel 的 drawCall??梢酝ㄟ^線選擇要debug的pixel,然后通過pixel history快速定位到要debug的drawCall

可以在右上角的 Debug in Assembly 和 Debug in HLSL 之間切換來選擇單步調(diào)試的方式。

