Unity&UE4屠龙术 - shader单步调试
首先表达一下个人对单步调试shader的看法。如果能单步调试shader,那自然是很强大,但是很多同学其实是并不需要的,因此,个人将shader单步调试称为屠龙术。就是因为有屠龙(开发分析复杂shader)的需求的场景实在的非常少。
要说最强大,也是个人最习惯用的帧调试器,那就是renderdoc。renderdoc非常强大易用,以至于主流游戏引擎比如Unreal Engine 4 和 unity都提供了对renderdoc的内建支持。renderdoc还有一个重要功能,就是提供了HLSL单步调试的能力。这次,我就要分享一下如何使用renderdoc的HLSL调试功能,来调试unity和UE的shader。
renderdoc 调试 unity shaderlab
前面已经提到renderdoc支持调试HLSL,unity shaderlab使用的表面上是CG,实质上是HLSL,所以当然可以用renderdoc单步调试unity shaderlab。
虽然unity也内置了帧分析器,但是感觉还是不够强大,除了replay功能之外缺失还是太多。
开启 Unity 的 shader 调试整体还是非常简单的,首先,在shader文件的 CGPROGRAM
块中键入:
#pragma enable_d3d11_debug_symbols
这步的目的是让 HLSL 编译后保存调试符号,且跳过HLSL的编译器优化。

接下来在unity中启用renderdoc支持,首先要在game窗口上右键,选择 load renderdoc

之后再game窗口右上角可以看见renderdoc的图标

点击图标完成抓帧,其中Camera.Render是game窗口的内容

定位到具体的drawCall,如果发现texture output上下颠倒可以使用 Flip the texture in the Y axis。

UE4 以 dx 的窗口系为标准,所以 openGL 模式下上下颠倒。Unity则相反,以 openGL 窗口为标准,在 DX 下会上下颠倒。
用鼠标右键在 Texture Viewer 的 Output 中定位到要调试的像素,

然后点击 Pixel Context 中的 debug 按钮即可开始愉快的单步调试

renderdoc 调试 UE4 shader
相比Unity,相信有调试UE4 shader需求的同学应该少了一大半,不过为了完整性,还是记录一下。
首先编辑 引擎目录 下的 Config/ConsoleVariable.ini
文件。

仔细阅读注释说明,保留HLSL调试信息并关闭HLSL编译器优化。

之后打开UE4内置的 renderdoc 插件。在 Edit -> Plugins 的内置插件(Built-in)中搜索 renderdoc 插件。

开启后重启并编译插件,之后可以在Editor viewer的右上角发现renderdoc的图标。

点击该图标,即可完成抓帧。在Event brower中定位到需要分析的drawCall。

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

用鼠标右键在 Texture Viewer 的 Output 中定位到要调试的像素,然后点击 Pixel Context 中的 debug 按钮即可开始调试(请务必确保该 drawcall 影响该 pixel,否则还是会显示该pixel的pixel history)

之后即可开始单步调试HLSL。调试非常方便,不仅可以step forward,还可以step backward。并且存在超方便的功能run to cursor,只要鼠标定位到要执行到的行数即可,连断点都可以不打。双击寄存器可以在变量(Variables面板中高亮变量),当然悬停也可以显示变量值。

renderdoc 的一些小技巧
其实不仅可以调试,还可以实时修改 shader,之后刷新就能看到效果。比如我把绘制人物的shader改为直接显示红色。


dx11(sm5)下默认使用延迟渲染,OutTarget0是color attachment
人物材质被修改后的效果可以在Texture viewer中查看。这个功能很便于开发shader,避免反复编译/重启游戏浪费时间。

如果要快速寻找需要 debug 的 pixel 的 drawCall。可以通过线选择要debug的pixel,然后通过pixel history快速定位到要debug的drawCall

可以在右上角的 Debug in Assembly 和 Debug in HLSL 之间切换来选择单步调试的方式。

