想象你是一家中央厨房的食客,点了一盘红烧肉,端上来却发现颜色不对——左半边红润油亮,右半边却黑得像炭。后厨几十位厨师各执一词,没人承认自己搞砸了。这时,你需要一位“现场侦探”:他不听辩解,而是在出菜的一瞬间把整条流水线按下暂停,然后从成品倒查回备菜台——切菜、传菜、调味,每一步都翻出记录给你看。在 GPU 的世界里,这桩“餐饮悬案”每天都在上演,那道菜叫作“渲染结果”,而着色器(Shader)就是掌勺的厨师。主角登场:RenderDoc 和 NVIDIA NSight Graphics,就是图形界的两位名侦探。本文会带你熟悉这两位侦探的装备——帧捕获、管线阶段检查、变量监控、性能分析,再用三起真实案件的手把手演示,让你在着色器出问题时,不再是满厨房乱转的帮厨,而是拿着线索冷静断案的侦探。
对 AI 从业者而言,图像生成、三维感知、渲染仿真都离不开 GPU 着色器,掌握 RenderDoc/NSight 的调试思维,等于握住了“看得见 GPU 内部计算”的钥匙,能显著加速渲染引擎开发、AI 可视化与性能调优工作。
目录
可视化演示
展示RenderDoc帧捕获回放、GPU渲染管线逐阶段检查与性能分析的全流程,含Draw Call追踪与瓶颈定位。
本节配有交互动效(进入视口后自动加载,约 3KB)。
帧捕获与回放流程 录制GPU渲染帧捕获Draw Call序列 回放分析逐帧查看资源状态变化 Frame = Σ DrawCall_i 帧捕获是GPU调试的基础如同行车记录仪
工具初识:两位厨房侦探(对应思维导图一级分支 1)
中央厨房里端出一盘半黑半红的红烧肉,后厨吵成一锅粥。这时需要的不是替罪羊,而是一位能“复盘现场”的侦探。GPU 世界就有两位风格迥异的侦探:RenderDoc 像一位独立开业的私家侦探,只带一把放大镜(开源、免费)就敢接跨品牌的大案子;NSight Graphics 则是 NVIDIA 大酒店自聘的安保主管,对自家一砖一瓦的脾气摸得门儿清。
两位侦探表面都做一件事——抓帧。抓帧不是拍照,而是在出菜瞬间把整条流水线的状态冻结并记录,之后可以一帧一帧回放。差别在于家底:RenderDoc 对 Vulkan、OpenGL、Direct3D 等主流 API 一视同仁,跨厂商通用;NSight Graphics 天生为 NVIDIA GPU 优化,能挖出硬件级性能计数器。选谁,取决于你的厨房是哪家装修的。
不管选谁,面板上都会出现两个最基础的指标:帧时间(渲染一帧花的秒数)与帧率(每秒渲染的帧数)。它们就像出菜速度和顾客满意度,互换关系很简单。
所以选侦探也是门学问:在混合品牌 GPU 的项目里,开源万能的 RenderDoc 是稳妥搭档;在 NVIDIA 为底的引擎里,NSight 这把原厂扳手更趁手。侦探能力不分高下,关键是谁更懂你的厨房。
- FPS(帧率)每秒能渲染并显示的帧数,好比厨房每秒能端出几盘菜。
- T_frame(帧时间)渲染单帧所需的秒数,即一道菜的平均出菜耗时。
- 倒数关系帧率越高,单帧耗时越短,两者乘起来正好等于 1。
帧捕获操作:按下暂停键(对应思维导图一级分支 2)
侦探进场第一步,永远是封锁现场。在图形世界里,这意味着让出菜口——显示器的交换链(Swapchain)——在即将送出画面的瞬间按下暂停,把那盘菜原封不动端进实验室。这一步在工具里就叫“帧捕获”,RenderDoc 中按一下 F12 即可,NSight 则提供工具栏上的捕获按钮。
捕获不是截屏。截屏只拿到成品菜的照片,捕获却把整条命令流冻结成了“录像带”。GPU 为这一帧执行过的所有绘制指令(Draw Call)都被记录,之后想停在哪一帧、哪一步,都由你说了算。正因为如此,捕获多发生在应用程序调用“提交帧”(Present)之前,侦探趁机插一杠子。
那么,一盘菜为什么拆得开?因为它本来就是一层层叠出来的:天空一层、地面一层、角色一层、特效一层,每个物体可能占多次绘制调用,像千层饼一样按深度与混合规则堆叠。最终像素颜色,本质上是所有图层贡献的叠加。
抓到帧后,实验室白板上会列出这场“烹饪”的全部案卷——绘制调用列表。侦探要做的是锁定可疑图层,然后进入真正的环节:沿管线逐阶段倒查。
- 绘制调用(I_i)一次 Draw Call 输出的颜色图像,好比千层饼中的一层食材。
- 叠加求和所有图层按照深度测试与混合规则逐层合成。
- 最终像素累加完成后写入帧缓冲,就是你看到的成品菜。
管线阶段检查:沿备菜台回走(对应思维导图一级分支 3)
案卷锁定后,侦探开始从出菜口倒着往回走。一道菜从原料到成品,至少要经过备菜(顶点处理)、传菜(光栅化)、调味(片元着色)三个环节。难点在于:上游环节出了问题,下游再努力也会把错误放大——厨师把土豆切成了砖头,调味再好端上桌也是砖头。
图形管线的三个关键环节同理:顶点着色器把三维模型坐标变换到裁剪空间;光栅化器把三角形切成屏幕上的像素格子;片元着色器再为每个格子计算最终颜色。RenderDoc 的 Mesh View(网格视图)和管线状态面板,就是为逐阶段审视这些输出而生的。
顶点变换是所有环节的地基。模型里每个顶点在自身坐标系定义(局部坐标),要依次经过模型矩阵(摆放位置)、视图矩阵(摄像机观察)、投影矩阵(近大远小),最终进入裁剪空间。三步合一就是鼎鼎大名的 MVP 变换。
侦探在 Mesh View 里看到的就是这些具体数字:如果顶点坐标跑出可视范围,或 w 分量出现负数,问题就锁死在“备菜”环节,接下来该翻食材(顶点数据)和配方卡(uniform)。
- 局部坐标(p_local)顶点在模型自己坐标系里的原始位置,如案板上未切的土豆。
- 模型与视图变换先摆进世界场景,再转到摄像机视角下。
- 投影变换模拟透视效果,把可视范围压到裁剪盒内。
资源变量监控:翻配方卡与冰箱(对应思维导图一级分支 4)
厨师做出怪味,除了手法问题,还可能因为拿错食材、看错配方。侦探在定点检查时会翻两样东西:厨房冰箱——纹理、顶点缓冲等资源;厨师口袋里的配方卡——uniform 常量。工具里的“资源视图”和“变量监控”面板,正是为此准备的。
纹理可以逐层查看 mipmap,顶点缓冲里每个字节都能摊开看,uniform 缓冲区的每个值也能直接读出。但有一个细节最容易出卖人:从顶点着色器传给片元着色器的 varying 变量,在片元里并不是某个顶点的原始值,而是光栅化期间在三角形内部做加权平均的结果。
这个加权平均的权重,由重心坐标(Barycentric Coordinates)决定。三角形内任意一点的重心坐标是三个权重系数,它们和为 1,分别代表该点离三个顶点的“亲近程度”。片元越靠近某个顶点,那个顶点的属性(颜色、法线、UV)贡献越大。
当侦探发现冰箱里一块肉形状正确、配方卡数值也对,却在片元里看到诡异颜色时,八成要回来检查这个插值链路——要么是顶点属性没写对,要么是重心坐标计算出了偏差。食材和配方都没问题之后,才能怀疑厨师的手法。
- 顶点属性(f_0/f_1/f_2)三角形三个顶点各自的颜色、法线或 UV 值。
- 重心坐标(b_0/b_1/b_2)片元在三角形内的位置权重,越靠近某顶点,对应权重越大。
- 加权平均三份属性按权重混合,得到片元看到的插值结果。
着色器调试:喊停的瞬间(对应思维导图一级分支 5)
食材、配方都检查完毕,怀疑还落在厨师手上时,就得使出终极手段:在颠勺的瞬间喊“停!”。厨房时间冻结,厨师的铲子悬在半空——这就是着色器调试器里的断点。RenderDoc 与 NSight 都允许在着色器源码的任意一行下断点,条件满足时,GPU 会停在被调试的那个顶点或像素上。
单步执行时,你能逐行看代码,同时观察局部变量的实时值:坐标算到哪一步了、临时颜色是多少、哪个 if 分支被走进了。若只想针对屏幕上某个像素调试,得先明确它的像素坐标——它由 NDC(标准设备坐标,范围 -1 到 1)换算而来。
换算公式并不复杂:NDC 坐标加 1 后除以 2,变成 0 到 1 的比例,再乘以屏幕宽高,就得到像素坐标。这也是调试视图中“点击某像素查看对应片元”背后的数学。
除了断点,Pixel History(像素历史)是更温柔的监控录像:一个像素最终颜色可能被多个三角形反复覆盖,它会列出每个三角形的贡献顺序和每一步颜色变化。断点和像素历史双管齐下,偶然的 Bug 就变成了可复现的现场,你不再靠“改一行碰运气”,而是看 GPU 一步步算给你看。
- NDC 坐标裁剪坐标除以 w 后得到的归一化坐标,范围在 -1 到 1 之间。
- 归一化映射先加 1 再除以 2,把范围平移到 0 到 1。
- 缩放像素乘以屏幕宽度 W,得到对应像素列号。
性能分析:哪道工序在磨洋工(对应思维导图一级分支 6)
有时菜没做错,就是上菜太慢。侦探这时掏出秒表,给流水线每个环节计时。NSight 的 Range Profiler 能统计各渲染阶段 GPU 耗时,GPU Trace 记录更底层的硬件活动;RenderDoc 的事件浏览器也能显示每个绘制调用的执行时间。目标只有一个:找出谁在拖后腿。
性能分析必须先分清楚是谁在等谁。CPU 像点菜的服务员,GPU 像做菜的厨师,两者并行工作、相互等待:CPU 提交绘制命令的速度慢,叫 CPU-bound;GPU 执行渲染的速度慢,叫 GPU-bound。因为并行流水线最终由慢的一侧决定节奏,帧总耗时近似等于两者中的较大值。
这也是为什么“只看帧率下降就盲目优化渲染”常常白费力气——也许瓶颈根本不在 GPU,而在 CPU 端的 draw call 提交太频繁。秒表数据会告诉你真实答案。
秒表结论常出人意料:你以为是片元着色器太沉重,结果瓶颈在顶点变换;你以为是三角形太多,结果是 Overdraw(同一像素被反复涂色)。有了阶段耗时数据,优化就从玄学变成了一道清晰的计算题:先砍最长的木板。
- CPU 时间应用提交绘制命令、更新 uniform 等逻辑开销,好比服务员记单与传菜。
- GPU 时间图形硬件执行顶点、光栅化、片元计算的实际耗时,好比厨师真正颠勺。
- 取最大值并行流水线中慢者决定整体节奏,因此瓶颈方主导帧耗时。
实战案例:三起“食物中毒”案件(对应思维导图一级分支 7)
装备齐了,来跟三起真实案件过招。案件一:某游戏角色只渲染出半边身体,像被无形的刀劈过;案件二:整个场景模型发黑,仿佛酱油倒了三瓶;案件三:帧率从 60 骤降到 20,操作卡成幻灯片。
案件一交给 RenderDoc。Mesh View 里看到部分顶点 w 分量为负,这些顶点在裁剪阶段被剔除,三角形因此“缺了一半”。案件二同样用 RenderDoc 的像素历史:片元里的漫反射项恒为 0,因为法线方向没有随模型矩阵正确变换,与光照方向的点积永远落在负数区。这背后的公式值得认识一下。
案件三交给 NSight:Range Profiler 柱状图显示片元阶段耗时占一帧 70%,进一步排查是半透明粒子 Overdraw 严重。把粒子特效分辨率降一档并合并绘制批次后,帧率回到 55。三起案件三种路径,破案逻辑却一致:先抓帧,再沿管线倒查阶段输出,最后锁定数据或代码问题。
- 点积(N·L)法线方向与光照方向的夹角余弦,夹角越小越亮。
- max 截断法线背光时点积为负,物理上不应贡献亮度,直接取 0。
- 系数与光强材质漫反射系数 k_d 与光源强度相乘,控制整体明暗。
排查思路:侦探的破案口诀(对应思维导图一级分支 8)
老侦探退休前留下一本工作手册,里面没有魔法,只有顺序:从后往前查,先看数据再看代码,先放大后修细节。这三条口诀,覆盖了绝大多数着色器疑难杂症。
从后往前查,指从输出合并阶段往顶点阶段倒推,利用像素历史快速排除后半段管线;先看数据,指优先检查顶点、纹理、uniform 这些输入是否正确,再怀疑算法本身——输入错,输出必错;先放大后修细节,则是把问题场景压缩到最小可复现实验,一个三角形能复现绝不放进整个场景。
当可疑环节不止一个时,最笨的办法是逐个试,最聪明的是二分定位:从管线中间掰开,看哪一半输出正常,再继续掰剩下的可疑区段。若有 n 个环节需要排查,二分法需要的检查次数是对数级别,效率远超线性逐个排查。
手册最后一页写着:大部分难题不是你不够聪明,而是检查顺序不对。RenderDoc 与 NSight 的每块面板,都在帮我们把“猜”变成“证”。带上侦探的耐心与工具的科学性,再隐蔽的着色器暗病,也终将被揪出来。
- 环节总数(n)需要排查的管线阶段或绘制调用数量。
- 二分对数每检查一次排除一半可能,所需次数是对数。
- 向上取整检查次数必须是整数,不足一次也按一次算。
AI 应用场景
游戏与数字人渲染 Bug 排查
阶段:3D渲染管线调试与验证
解决的问题:传统方式下,渲染异常时开发者只能反复改 Shader 代码重新编译试错,一次黑屏可能要调试一整天;用 RenderDoc 抓帧后,GPU 执行的命令流被完整冻结,可以从 Mesh View 查看顶点输出、用 Pixel History 查看片元贡献,把“改代码碰运气”变成“看数据定位”。
具体案例:某 AIGC 虚拟人项目在接入新表情系统后,脸部模型一半消失。用 RenderDoc 抓帧发现部分顶点 w 分量为负被裁剪,定位到模型矩阵的平移分量写错,修正后表情系统恢复。
移动端 GPU 兼容性调试
阶段:跨平台迁移与质量保障
解决的问题:同一份着色器代码在不同手机 GPU 上显示效果不同,生产环境难以复现;NSight Graphics 与 RenderDoc 支持按设备抓帧对比,能逐阶段查看顶点与片元输出,定位究竟是半精度浮点精度不足,还是驱动对特定指令的优化差异。
具体案例:端侧 AI 特效 App 在部分 Adreno 芯片上出现模糊条纹,抓帧对比发现片元中的中间变量被降为半精度存储,导致深度值抖动,改为精度更高的插值计算后问题消除。
渲染性能调优
阶段:性能分析与瓶颈定位
解决的问题:传统优化靠肉眼观察和猜测,往往优化了非瓶颈环节却没有效果;使用 NSight Range Profiler 记录各阶段 GPU 耗时,可量化 CPU-bound 与 GPU-bound,根据瓶颈数据决定是减少绘制调用,还是降低片元复杂度、减少 Overdraw。
具体案例:某数字孪生城市项目帧率长期低于 30,性能分析发现半透明建筑群 Overdraw 严重,将混合渲染改为批次合并且降低粒子分辨率,帧率提升至 55。
Python 演示
# 模拟RenderDoc式逐阶段调试:定位三角形"一半消失且发黑"的Bugimport math class StageDebugger: """模拟图形管线各阶段的调试检查,对应抓帧后的逐阶段追踪""" def __init__(self): self.check_log = [] # 调试日志,像RenderDoc的事件浏览器 self.vs_list = [] # 顶点着色器输出列表 self.ps_list = [] # 片元着色器输出列表 def run_vertex(self, local_pos, mvp, normal): """顶点着色阶段:做MVP变换并检查w分量是否触发裁剪""" x = (mvp[0] * local_pos[0] + mvp[4] * local_pos[1] + mvp[8] * local_pos[2] + mvp[12]) y = (mvp[1] * local_pos[0] + mvp[5] * local_pos[1] + mvp[9] * local_pos[2] + mvp[13]) z = (mvp[2] * local_pos[0] + mvp[6] * local_pos[1] + mvp[10] * local_pos[2] + mvp[14]) w = (mvp[3] * local_pos[0] + mvp[7] * local_pos[1] + mvp[11] * local_pos[2] + mvp[15]) self.vs_list.append((x, y, z, w)) if w <= 0: self.check_log.append("顶点%s的w=%f<=0, 会被裁剪" % (str(local_pos), w)) return x / w, y / w, z / w def run_pixel(self, ndc_pos, normal, light_dir): """片元着色阶段:计算漫反射亮度并记录结果""" nx, ny, nz = normal lx, ly, lz = light_dir dot = nx * lx + ny * ly + nz * lz if abs(dot) < 1e-4: self.check_log.append("法线与光照点积接近0, 检查法线是否未归一化") diff = max(dot, 0.0) self.ps_list.append(diff) return diff def debug_frame(self, vertices, mvp, light_dir): """抓帧后逐阶段检查整帧数据:先顶点后片元""" for i, (pos, normal) in enumerate(vertices): clip = self.run_vertex(pos, mvp, normal) shade = self.run_pixel(clip, normal, light_dir) self.check_log.append("顶点%d -> 片元亮度 %.3f" % (i, shade)) return self.check_log if __name__ == "__main__": # 故意构造带Bug的模型矩阵:z分量被错误写入w列, 导致部分顶点w<=0 bad_mvp = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -5, 1] tris = [ ((0, 1, 0.1), (0, 0, 1)), ((1, 0, 0.1), (0, 0, 1)), ((-1, 0, 0.3), (0, 0, 1)), ((0, -1, 0.3), (0, 0, 1)), ] dbg = StageDebugger() logs = dbg.debug_frame(tris, bad_mvp, (0, 0, 1)) for line in logs: print(line)
bad_mvp = [1, 0, 0, 0, ...]构造一个按列主序排布的 4×4 矩阵,其中-5被错误写在 w 列,模拟真实项目里模型矩阵写错的场景。w = ... + mvp[15]计算裁剪坐标的 w 分量,管线中 w 是否为正决定顶点会不会被裁剪掉。if w <= 0:正是 Mesh View 里“顶点被裁剪”提示的判据,把可疑顶点记录下来。diff = max(dot, 0.0)片元阶段漫反射公式中的截断操作,负值点积代表背光面,亮度取 0。dbg.debug_frame(tris, bad_mvp, ...)等价于按下 F12 后自动抓帧并逐阶段跑完全部顶点与片元,最后打印案卷日志。
常见误区
误区抓帧不就是把屏幕上显示的图截下来吗?画面不对,截下来看成品不就行了?
正解截屏只拿到成品照片,抓帧却冻结了 GPU 整条命令流——每个绘制调用的输入输出、每个阶段的中间数据都可回放。侦探要的是监控录像,不是一张现场合影。
为何常见:两种操作的结果都呈现在界面上,外形相似,初学者极易混淆。
误区程序运行得好好的,但按 F12 完全没有反应,肯定是 RenderDoc 的 Bug。
正解抓不到帧通常是你没在正确时机调用捕获 API(如未插入标记,或交换链的帧提交方式与工具预期不符),也可能焦点窗口被覆盖导致快捷键失效。先检查应用是否双窗口渲染、是否使用了加载器注入,再怀疑工具本身。
为何常见:快捷键捕获得像“魔法”,一旦魔法失灵,人下意识怪魔法棒而不怪施法手势。
误区画面颜色不对,肯定是片元着色器的锅,直接在里面加断点、改逻辑就行。
正解管线是串联的:顶点输出错、光栅化插值错,片元再对也白搭。正确顺序是先看顶点阶段的输出数据和裁剪结果,再沿管线往下走,用 Mesh View 和像素历史快速排除前半段。
为何常见:片元着色器直接决定最终像素颜色,最直观、最容易被当成“第一嫌疑人”。
误区NSight 是 NVIDIA 给玩家测游戏帧率的工具,专业开发中没什么用。
正解NSight Graphics 是面向开发者的专业图形调试器,支持 DX/Vulkan 的着色器逐行调试、Range Profiler 性能区间分析、GPU Trace 硬件级追踪,定位精度比通用工具更细。
为何常见:NSight 与 GeForce Experience 等消费级软件同属一家,让很多人误以为它只是“跑分工具”。
误区在调试视图里改了着色器代码,GPU 就应该立刻用新代码渲染出效果,像网页热重载一样。
正解工具的“编辑-重放”机制修改的是已捕获帧的数据,改完需要点击应用并重新重放该帧才能看到效果,它不会实时连动正在运行的主程序。
为何常见:编辑器界面做得太像 IDE,容易让人下意识期待即时编译生效。
面试题
Q1. RenderDoc 最擅长做的事情是什么?
- A.捕获一帧画面并回放调试← 正确答案
- B.自动生成高质量着色器代码
- C.对 GPU 进行硬件超频调校
- D.编译并优化整个游戏引擎
答案:A。RenderDoc 的核心定位是帧捕获与回放调试,像侦探调取监控录像一样逐阶段复现渲染过程。B 是编辑器职责,C 是超频软件,D 是引擎构建工具,都不是 RenderDoc 的主业。
Q2. 在 RenderDoc 中执行“帧捕获”时,工具实际做了什么?
- A.从屏幕直接截取一张位图保存
- B.拦截 GPU 命令流并记录绘制过程← 正确答案
- C.读取显存中所有纹理的原始内容
- D.调用操作系统截图 API 生成图片
答案:B。帧捕获的本质是在交换链提交前拦截并记录整条 GPU 命令流,而不只是成品位图。A 和 D 是截图,C 只是资源导出中的一部分,均未触及“回放命令流”这一核心。
Q3. 顶点着色器输出的 w 分量出现负数时,最可能的结果是?
- A.片段亮度自动增加一倍高亮显示
- B.模型颜色反向变成黑白底片效果
- C.对应顶点被裁剪导致模型部分消失← 正确答案
- D.纹理坐标翻转使贴图上下颠倒
答案:C。裁剪规则要求 w 必须为正,w≤0 的顶点会被判定在视锥之外直接剔除,就像食材被挡在案板外,菜自然缺一角。A、B、D 分别是亮度、颜色、UV 问题,与 w 分量无关。
Q4. 以下哪些情况适合优先使用 RenderDoc 排查?
- A.画面出现类似黑屏或花屏的错误← 正确答案
- B.模型某部分莫名消失或严重变形← 正确答案
- C.需要实时监控程序内存的泄漏情况
- D.颜色光照异常且难以确定出错阶段← 正确答案
答案:ABD。黑屏、模型消失、颜色异常都是渲染管线问题,可通过抓帧逐阶段定位。C 是内存问题,属于 CPU 侧的调试工具范畴,RenderDoc 不管内存泄漏。
Q5. 片元着色器中接收的 varying(顶点→片元属性)默认是什么计算方式?
- A.取三个顶点中离片元最近的值
- B.按重心坐标对顶点属性加权平均← 正确答案
- C.取三个顶点属性中的最大值使用
- D.在屏幕空间按水平距离线性平铺
答案:B。光栅化阶段会按重心坐标对三个顶点属性做加权平均,权重和为 1。A、C 分别是最近邻和取最大,D 是屏幕空间线性插值,均不符合 GPU 的默认行为。
Q6. 帧率 60 FPS 时,渲染一帧的耗时约为多少?
- A.约 16.7 毫秒← 正确答案
- B.约 1.67 秒
- C.约 167 毫秒
- D.约 6.7 分钟
答案:A。帧时间与帧率互为倒数,1 秒除以 60 约等于 0.0167 秒即 16.7 毫秒。其余选项数量级错误,记住“倒数关系”即可快速排除。
Q7. NSight Graphics 相比 RenderDoc 的典型优势有哪些?
- A.对 NVIDIA 硬件性能数据采集更深入← 正确答案
- B.内置 Range Profiler 等专业分析器← 正确答案
- C.支持离线编译任意语言的手机应用
- D.可捕获并回放 CPU 端的全部系统调用
答案:AB。NSight 由 NVIDIA 官方打造,深度访问硬件计数器和性能分析器是其核心优势。C 是跨语言编译问题,D 是 CPU 调试器(如 gdb)的范围,均与 NSight 图形调试定位不符。
Q8. RenderDoc 中 Pixel History(像素历史)不会提供下列哪项信息?
- A.该像素被哪些图元覆盖及其执行顺序
- B.每个阶段输出的颜色与深度值对比
- C.自动修复着色器源码中的全部错误← 正确答案
- D.纹理采样命中的具体 mip 层级数据
答案:C。Pixel History 是“监控录像回放”,会列出图元覆盖顺序、阶段颜色、深度和纹理采样信息。但工具只负责展示数据,不会自动修复源码,C 明显超出调试器职责。
Q9. 片元着色阶段出现全黑输出,可能的原因有哪些?
- A.纹理采样坐标 UV 超出正常范围← 正确答案
- B.法线未归一化导致光照点积为负← 正确答案
- C.Uniform 缓冲没有正确绑定到管线← 正确答案
- D.顶点缓冲索引数组发生整数溢出
答案:ABC。UV 越界会采样到黑边,法线长度异常会让点积偏小甚至为负,uniform 未绑定会让参数取默认值导致亮度为 0。D 的索引溢出通常引发崩溃或错乱几何,而非单纯全黑。
Q10. 通常先检查下面哪个阶段,能最快排除“顶点变换错误”?
- A.顶点着色器的输出数据与裁剪结果← 正确答案
- B.帧缓冲区中最终合成的完整画面
- C.交换链是否启用了垂直同步等待
- D.显示器的色彩空间转换是否准确
答案:A。想验证顶点变换是否出错,直接看顶点着色器输出(Mesh View)最有效,别等待最终画面。B、C、D 都位于管线下游,问题溯源应遵循“从上游往下游”的顺序。