使用Nsight调试渲染
本文简单介绍如何使用Nsight Graphics软件在Minecraft模组开发环境下调试渲染. 使用该软件需要有Nvidia显卡, 不满足条件可以使用同类软件renderdoc, 但是本文不讨论后者的使用.
强烈建议在遇到任何渲染问题后, 都应该先使用Nsight或者同类软件进行分析后再向他人提问或咨询.
下载
https://developer.nvidia.com/nsight-graphics/get-started
软件应该没有汉化, 考虑到界面会出现非常大量的渲染专有名词, 还是推荐使用英文界面.
挂载到模组开发环境

打开软件后如图, 点击Start Activity然后在Application Executable填写你的IDE的可执行程序文件地址. 下面可以选择会话类型, 一般只需要使用默认的Frame Debugger.

有的时候Nsight会发现其他程序有进程注入等操作, 提示干扰进程, 如steam. 点击keep无视即可, 如果无法运行则可以考虑关闭干扰进程.
接下来在IDE内正常开启游戏即可, 本文使用的环境是26.1 snapshot7 Neoforge, 运行runClient开启游戏. Nsight可以和java调试器共存.

打开游戏后可以看到左上角有一个悬浮窗, 实时显示帧率和帧时间, 并提示你按下F11来抓帧.
帧调试器使用方法
作者也仅使用过部分功能, 此处仅讲述作者常用的功能.
抓帧

按下F11后会抓取下一帧并记录这一帧的所有图形API调用(在这里是OpenGL,不久的将来在MC将可以使用Vulkan), 并出现一个窗口可以查看每一个drawcall绘制的内容, 如图, 可以看到绘制了一个区块的地形.
打开帧调试器
此时还没有真正打开帧调试器, 此时我们再回到Nsight, 在Start Activity面板里选择Attch并选择MC对应的进程.


启动后会显示类似如图的内容, 信息量非常大乍一看非常吓人, 我们逐个面板看. 如果关闭了某个面板或者读者找不到某个面板, 可以在程序菜单栏Frame Debugger里打开.
事件

Events显示被抓一帧内的所有事件, 也就是OpenGL调用, 高亮的drawcall也就是发生了绘制的调用. 点击任意事件下方的EventDetails会显示调用的详细参数. 切换到API Statistics可以看到看到各种调用的数量,CPU时间和GPU时间统计.
事件条

位于画面中间上部的Scrubber则是将事件按时间轴排列, 可以切换时间轴为CPU时间或GPU时间等, 也可以添加对某些状态的监控, 看到一些状态的切换.比如图中第三行, 显示Program Ranges, 我们就可以直观看到MC在何时切换了着色器程序.
渲染模板预览

画面上部右侧的Current Target显示当前绑定的渲染模板, 可以看到颜色和深度, 如果启用了模板测试则也可以在这里看到模板等. 点击蓝字可以放大查看
DrawCall详细信息

API Inspector则可能是最重要的面板了, 在这里可以看到一个drawcall有关的几乎所有信息.信息太多下面依旧只列举部分个人常用功能.
几何预览

点击Vtx Spec面板的Geometry,即可看到这次drawcall所提交的顶点,可以切换到Memory选项卡来查看具体的内存内容.
着色器面板
VS,TCS,TES,GS,FS,CS均是各类着色器对应的面板. 在MC中, 渲染管线一般只使用两种着色器, VS和FS, 即顶点着色器和片段着色器, 点击对应面板即可看到着色器状态, 使用的材质, 绑定的Uniform等.
一个颇为有用的功能是现场编辑着色器.

在着色器状态显示里, 点击Source按钮即可看到着色器代码, 再点击EditShader, 就能在右侧面板里直接修改着色器了, 点击编译后再次按F11结束抓帧即可使刚编辑的着色器生效.
显然在这里编辑的着色器关闭游戏后不会被保存, 调试好效果记得写回到文件.
像素历史

在打开某个具体texture后, 点击红框按钮再点击任意像素, 即可看到像素的历史, 可以每个改变了这个像素的drawcall.
Obj浏览器

可以看到创建的各种buffer或者其他对象.对于buffer, 点击Open In Resource Viewer可以直接看到其内存.

对于某个特定的Resource, 可以点击红框处按钮配置数据的显示格式.这样在知道格式时就不用看一堆字节.