HR

hengle/renderdocmcp2

开发工具
33 stars 0 forks 质量 90 趋势 90

全自动化截帧到逆向还原分析,配合unityMCP效果更佳

概览

从安装到精通 —— 让 AI 帮你分析 GPU 截帧、逆向着色器、导出 Unity 资源 RenderDoc MCP Server 是一个 ,它充当 AI 智能体与 RenderDoc 之间的桥梁。装上它之后,你可以用自然语言让 AI: - 🔍 分析 GPU 截帧中的每一个绘制调用 - 🎨 自动识别贴图用途(漫反射、法线、PBR 等) - 💎 逆向还原着色器(HLSL/GLSL/SPIR-V) - 📊 读取 Shader 运行时参数的真实值 - 🐛 逐行调试像素/顶点着色器 - 📤 一键导出模型+贴图+材质到 Unity - ⚡ 分析 GPU 性能瓶颈 因为 RenderDoc 内置的 Python 是 3.6 版本,而 MCP SDK 需要 Python 3.10+。两个 Python 版本无法直接互通,所以使用 来桥接: - :运行在系统 Python 3.10+ 上,负责与 AI 通信 - :运行在 RenderDoc 内置的 Python 3.6 上,负责实际操作 GPU 数据 - :通过 %TEMP%/renderdoc_mcp_ipc/ 目录下的 JSON 文件交换数据 1. 访问 https://renderdoc.org/builds 2. 下载最新稳定版安装包 3. 安装到默认路径(如 C:\Program Files\RenderDoc) 4. 验证:运行 qrenderdoc.exe 能正常打开 1. 打开 RenderDoc 2. 菜单 File > Launch Application 3. 选择你要截帧的程序(游戏/图形应用) 4. 点击 Launch 5. 在应用运行时按 F12 或 Print Screen 截帧 6. 截帧文件保存为 .rdc 格式 如果 pip install -e . 报错 Unable to determine which files to ship inside the wheel,确保 pyproject.toml 包含:

README

RenderDoc MCP Server 完整使用手册

从安装到精通 —— 让 AI 帮你分析 GPU 截帧、逆向着色器、导出 Unity 资源

版本: 1.5.0 | 工具数量: 37 个 | 更新日期: 2026-04-14


📖 目录


第一章:概述与架构

1.1 这是什么?

RenderDoc MCP Server 是一个 MCP(Model Context Protocol)服务器,它充当 AI 智能体与 RenderDoc 之间的桥梁。装上它之后,你可以用自然语言让 AI:

  • 🔍 分析 GPU 截帧中的每一个绘制调用
  • 🎨 自动识别贴图用途(漫反射、法线、PBR 等)
  • 💎 逆向还原着色器(HLSL/GLSL/SPIR-V)
  • 📊 读取 Shader 运行时参数的真实值
  • 🐛 逐行调试像素/顶点着色器
  • 📤 一键导出模型+贴图+材质到 Unity
  • ⚡ 分析 GPU 性能瓶颈

1.2 三层架构

┌─────────────┐     stdio      ┌──────────────────┐    文件IPC     ┌──────────────────┐
│  AI / IDE   │ ◄────────────► │  MCP Server      │ ◄────────────► │  RenderDoc 扩展  │
│ (WorkBuddy) │                │  (Python 3.10+)  │                │  (Python 3.6)    │
│             │                │  server.py       │                │  __init__.py     │
└─────────────┘                └──────────────────┘                └──────────────────┘
                                       │                                    │
                                  37 个 MCP 工具                    pyrenderdoc API
                                                                   (renderdoc.dll)

为什么需要三层?

因为 RenderDoc 内置的 Python 是 3.6 版本,而 MCP SDK 需要 Python 3.10+。两个 Python 版本无法直接互通,所以使用 文件 IPC(进程间通信) 来桥接:

  • MCP Server:运行在系统 Python 3.10+ 上,负责与 AI 通信
  • RenderDoc 扩展:运行在 RenderDoc 内置的 Python 3.6 上,负责实际操作 GPU 数据
  • IPC 通信:通过 %TEMP%/renderdoc_mcp_ipc/ 目录下的 JSON 文件交换数据

1.3 系统要求

组件 最低要求
操作系统 Windows 10/11, Linux, macOS
RenderDoc v1.20+ (推荐 v1.30+)
系统 Python 3.10+ (用于运行 MCP Server)
MCP 客户端 WorkBuddy / Claude Desktop / 任何 MCP 兼容客户端
磁盘空间 ~50MB (不含截帧文件)

第二章:环境准备

2.1 安装 RenderDoc

Windows:

  1. 访问 https://renderdoc.org/builds
  2. 下载最新稳定版安装包
  3. 安装到默认路径(如 C:\Program Files\RenderDoc)
  4. 验证:运行 qrenderdoc.exe 能正常打开

Linux (Ubuntu/Debian):

sudo apt-get install renderdoc
# 或从 PPA 安装最新版
sudo add-apt-repository ppa:baldurk/renderdoc
sudo apt-get update
sudo apt-get install renderdoc

2.2 安装 Python 3.10+

如果系统已有 Python 3.10+,可跳过。

Windows:

# 使用 winget
winget install Python.Python.3.12

# 或访问 https://www.python.org/downloads/ 手动下载

Linux:

sudo apt-get install python3.12 python3.12-venv python3-pip

验证:

python --version
# 应显示 Python 3.10+ 的版本号

2.3 获取一个 GPU 截帧

如果你还没有 .rdc 截帧文件,可以这样获取:

  1. 打开 RenderDoc
  2. 菜单 File > Launch Application
  3. 选择你要截帧的程序(游戏/图形应用)
  4. 点击 Launch
  5. 在应用运行时按 F12 或 Print Screen 截帧
  6. 截帧文件保存为 .rdc 格式

第三章:安装与配置

3.1 安装 MCP Server

# 1. 进入项目目录
cd renderdoc-mcp

# 2. 安装(开发模式,方便更新)
pip install -e .

# 验证安装成功
renderdoc-mcp --help
# 或
python -m src.server --help

如果 pip install -e . 报错 Unable to determine which files to ship inside the wheel,确保 pyproject.toml 包含:

[tool.hatch.build.targets.wheel]
packages = ["src"]

3.2 安装 RenderDoc 扩展

扩展是一个 Python 文件,需要放到 RenderDoc 的扩展目录中。

Windows 路径:

C:\Users\\AppData\Roaming\qrenderdoc\extensions\renderdoc_mcp\__init__.py

Linux 路径:

~/.local/share/qrenderdoc/extensions/renderdoc_mcp/__init__.py

操作步骤:

  1. 创建扩展目录:

    # Windows
    mkdir "$env:APPDATA\qrenderdoc\extensions\renderdoc_mcp"
    

Linux

mkdir -p ~/.local/share/qrenderdoc/extensions/renderdoc_mcp

2. 将扩展文件复制到该目录(如果项目中已有,直接复制)

3. 重启 RenderDoc

4. 验证:在 RenderDoc 中,菜单 `Tools > RenderDoc MCP > Status`,应显示 "MCP bridge is RUNNING"

### 3.3 配置 MCP 客户端

根据你使用的 MCP 客户端进行配置。

#### WorkBuddy 配置

编辑 `~/.workbuddy/mcp.json`:

```json
{
  "mcpServers": {
    "renderdoc": {
      "command": "renderdoc-mcp",
      "env": {}
    }
  }
}

或者使用 Python 模块方式:

{
  "mcpServers": {
    "renderdoc": {
      "command": "python",
      "args": ["-m", "src.server"],
      "cwd": "C:\\Users\\admin\\WorkBuddy\\Claw\\renderdoc-mcp",
      "env": {}
    }
  }
}

Claude Desktop 配置

编辑 claude_desktop_config.json:

{
  "mcpServers": {
    "renderdoc": {
      "command": "renderdoc-mcp"
    }
  }
}

3.4 完整启动流程

每次使用前需要按照以下顺序启动:

方式一(手动启动):
步骤 1:打开 RenderDoc (qrenderdoc.exe)
    ↓
步骤 2:加载截帧文件 (File > Open Capture)
    ↓
步骤 3:确认扩展运行 (Tools > RenderDoc MCP > Status → "RUNNING")
    ↓
步骤 4:启动/重启 MCP 客户端 (WorkBuddy / Claude Desktop)
    ↓
步骤 5:在 AI 对话中使用 RenderDoc 工具

方式二(自动启动 🆕):
步骤 1:启动 MCP 客户端 (WorkBuddy / Claude Desktop)
    ↓
步骤 2:在 AI 对话中输入 "打开截帧 C:\path\to\capture.rdc"
    ↓
步骤 3:AI 调用 launch_renderdoc() → 自动启动 RenderDoc + 加载截帧 + 等待桥接就绪
    ↓
步骤 4:直接开始分析!

💡 提示:launch_renderdoc 工具会自动查找 qrenderdoc 可执行文件,启动后等待 MCP 桥接就绪(最多30秒)。如果 RenderDoc 已经在运行,会自动切换为 open_capture 以提高速度。

⚠️ 注意:使用方式一时,RenderDoc 必须先打开并加载截帧,然后才能启动 MCP Server。否则工具调用会超时。


第四章:验证安装

4.1 快速健康检查

在 AI 对话中输入:

帮我检查 RenderDoc MCP 是否连接正常

AI 会调用 ping() 工具,正常响应应返回:

{"status": "ok", "server": "renderdoc_mcp", "ipc_dir": "C:\\Users\\...\\renderdoc_mcp_ipc"}

4.2 查看截帧状态

查看当前截帧的基本信息

AI 会调用 get_capture_status(),返回:

{
  "loaded": true,
  "api": "Vulkan",
  "renderer": "AMD Radeon RX 6800",
  "frameNumber": 8228,
  "draws": 125,
  "dispatches": 0,
  "calls": 1547
}

4.3 如果不工作

症状 可能原因 解决方法
ping 超时 RenderDoc 未打开 先打开 RenderDoc
ping 超时 扩展未加载 检查扩展目录路径是否正确
ping 超时 截帧未加载 先在 RenderDoc 中打开 .rdc 文件
“Unknown method” 扩展版本旧 更新扩展 __init__.py
工具数量不对 Server 或扩展不匹配 同时更新 server.py 和 init.py

第五章:37个工具详解

📡 类别一:连接管理 (2个)

ping

检查 RenderDoc 桥接是否在线。

用法:ping
参数:无
返回:{status: "ok", server: "renderdoc_mcp", ipc_dir: "..."}

使用场景:每次开始工作前先 ping 一下,确认连接正常。


get_capture_status

检查截帧加载状态和图形 API 信息。

用法:get_capture_status
参数:无
返回:{loaded, api, renderer, frameNumber, draws, dispatches, calls}

返回字段说明:

字段 说明
loaded 是否已加载截帧
api 图形 API (D3D11/D3D12/Vulkan/OpenGL)
renderer GPU 名称
frameNumber 帧号
draws Draw Call 数量
dispatches Compute Dispatch 数量
calls 总 API 调用数

📂 类别二:截帧管理 (3个)

list_captures

列出指定目录下的所有 .rdc 截帧文件。

用法:list_captures(directory)
参数:directory - 要搜索的目录路径
返回:[{name, path, size}, ...]

示例:

列出 C:\Captures 目录下的所有截帧文件
→ list_captures("C:\\Captures")

open_capture

在 RenderDoc 中打开一个截帧文件。

用法:open_capture(capture_path)
参数:capture_path - .rdc 文件的绝对路径
返回:{opened: "path"}

示例:

打开截帧文件 C:\Captures\game_frame.rdc
→ open_capture("C:\\Captures\\game_frame.rdc")

launch_renderdoc 🆕

启动 RenderDoc 应用程序并打开一个 .rdc 截帧文件。无需提前打开 RenderDoc。

用法:launch_renderdoc(capture_path, renderdoc_path)
参数:
  capture_path: str       .rdc 文件的绝对路径(必填)
  renderdoc_path: str     qrenderdoc 可执行文件路径(可选,自动检测)
返回:{launched, exe, capture, pid, bridgeReady, waitTime, fileSizeMB}

自动查找 qrenderdoc 的搜索顺序:

  1. 用户指定路径 (renderdoc_path 参数)
  2. RENDERDOC_PATH / RENDERDOC_MODULE_PATH 环境变量
  3. 系统 PATH
  4. 常见安装路径(Windows: C:\Program Files\RenderDoc\,Linux: /usr/bin/,macOS: /Applications/)

智能行为:

  • 如果 RenderDoc 已在运行且 MCP 桥接可用 → 自动切换为 open_capture(更快)
  • 🆕 根据文件大小动态等待:200MB → 90s
  • 超时后不报错——返回 bridgeReady=false + 友好提示,用 ping() 检查后续状态
  • 返回 PID 和等待时间信息
  • 兼容新旧版本 RenderDoc 的 LoadCapture API(自动适配 4/5 参数签名)

⚠️ 注意:加载大截帧(>200MB)可能需要较长时间。如果 MCP 请求超时,RenderDoc 仍会在后台继续加载,等待完成后再用 ping 检查桥接状态即可。

示例:

启动 RenderDoc 并加载截帧
→ launch_renderdoc("C:\\Captures\\game_frame.rdc")
→ 返回:{launched: true, exe: "C:\\Program Files\\RenderDoc\\qrenderdoc.exe",
         capture: "C:\\Captures\\game_frame.rdc", pid: 12345, bridgeReady: true, waitTime: "5.0s"}

与 open_capture 的区别:

open_capture launch_renderdoc
前提条件 RenderDoc 必须已打开 无前提,自动启动
速度 即时 需等待启动(~5-30s)
适用场景 切换截帧 从零开始打开截帧

🎨 类别三:DrawCall 分析 (3个)

get_draw_calls

获取帧内所有绘制调用,支持多种过滤条件。

用法:get_draw_calls(include_children, marker_filter, only_actions, event_id_min, event_id_max)
参数:
  include_children: bool = True   是否包含子操作
  marker_filter: str = ""         按 Marker 名称过滤
  only_actions: bool = False      仅返回实际 Draw/Dispatch
  event_id_min: int = 0           最小事件 ID (0=不限)
  event_id_max: int = 0           最大事件 ID (0=不限)
返回:{count, actions: [{eventId, name, flags, numIndices, numInstances, depth}, ...]}

返回字段说明:

字段 说明
eventId 事件 ID(全局唯一,用于其他工具的参数)
name 名称(Marker 名或 “Action N”)
flags 操作标志位(Draw=64, Dispatch=128 等)
numIndices 索引/顶点数(三角形数 = numIndices / 3)
numInstances 实例数(GPU Instancing)
depth 层级深度(嵌套在 Marker 内的深度)

示例:

获取所有绘制调用
→ get_draw_calls()

只看事件 60-100 之间的操作
→ get_draw_calls(event_id_min=60, event_id_max=100)

搜索名称包含 "Eye" 的操作
→ get_draw_calls(marker_filter="Eye")

get_frame_summary

获取帧的统计摘要。

用法:get_frame_summary
参数:无
返回:同 get_capture_status

get_draw_call_details

获取单个 DrawCall 的详细信息。

用法:get_draw_call_details(event_id)
参数:event_id - 事件 ID
返回:{eventId, vertexShader, fragmentShader, renderTargets, depthTarget, viewport}

🔧 类别四:管线状态 (1个)

get_pipeline_state

获取指定事件的完整渲染管线状态。

用法:get_pipeline_state(event_id)
参数:event_id - 事件 ID
返回:{shaders: {vertex, fragment, ...}, renderTargets, depthTarget}

每个 shader 条目包含:

字段 说明
shaderId 着色器资源 ID
entryPoint 入口函数名
textureCount 绑定纹理数
cbufferCount 常量缓冲区数
samplerCount 采样器数

常用场景:确定一个 DrawCall 使用了哪些着色器,绑定了多少纹理。


💎 类别五:着色器分析 (4个)

get_shader_info

获取着色器的详细信息 + 反汇编 + 绑定纹理。这是最常用的着色器分析工具。

用法:get_shader_info(event_id, stage)
参数:
  event_id: int   事件 ID
  stage: str      "vertex" | "fragment"/"pixel" | "geometry" | "compute" | "hull"/"tess_ctrl" | "domain"/"tess_eval"
返回:{shaderId, pipelineId, stage, entryPoint, disassemblyTargets, disassembly,
       inputs, outputs, boundTextures, constantBuffers, samplers}

返回字段详解:

字段 说明
disassemblyTargets 可用的反汇编目标列表(如 [“SPIR-V (RenderDoc)”, “AMDIL”, “RDNA2 gfx1030”, …])
disassembly 各目标的反汇编代码(字典)
sourceFiles 嵌入的源码文件(如有)
inputs 着色器输入签名
outputs 着色器输出签名
boundTextures 绑定纹理列表(含 slot、resourceId、尺寸、格式、推断角色)
constantBuffers 常量缓冲区(含变量名和运行时值)
samplers 采样器状态

reverse_shader

一站式着色器逆向 —— 与 get_shader_info 功能相同,但语义更明确。

用法:reverse_shader(event_id, stage)
参数:同 get_shader_info
返回:同 get_shader_info

何时使用:当你想完整理解一个着色器在做什么的时候。


get_bound_textures

获取着色器某个阶段绑定的所有纹理,含 自动角色推断。

用法:get_bound_textures(event_id, stage)
参数:
  event_id: int   事件 ID
  stage: str      着色器阶段
返回:[{slot, name, bind, resourceId, texName, width, height, format, role}, ...]

角色推断规则:

关键词匹配 推断角色 说明
albedo, diffuse, basecolor, _col, maintex albedo 基础颜色贴图
normal, nrm, bump, _n_ normal 法线贴图
metallic, metalness, _met metallic 金属度贴图
rough, roughness, _rgh, smoothness roughness 粗糙度贴图
ao, occlusion, _occ ao 环境光遮蔽
emissive, emission, glow emissive 自发光贴图
env, cubemap, reflection, ibl environment 环境反射
shadow, shadowmap shadow 阴影贴图
BC5/RG 格式 normal 格式启发推断
BC6H/HDR 格式 environment 格式启发推断

find_draws_by_texture

搜索使用了指定纹理名称的所有 DrawCall。

用法:find_draws_by_texture(texture_name)
参数:texture_name - 部分匹配的纹理名称(如 "eye", "skin")
返回:{textureIds, draws: [{eventId, name}], note}

find_draws_by_shader

按着色器名称搜索 DrawCall。

用法:find_draws_by_shader(shader_name, stage)
参数:
  shader_name: str   部分匹配的着色器名称
  stage: str = ""    可选阶段过滤
返回:搜索结果

⚠️ 此功能在扩展端尚未完全实现。


find_draws_by_resource

按资源 ID 搜索 DrawCall。

用法:find_draws_by_resource(resource_id)
参数:resource_id - 资源 ID
返回:搜索结果

⚠️ 此功能在扩展端尚未完全实现。


📦 类别六:资源检查 (4个)

get_textures

列出截帧中所有存活的纹理。

用法:get_textures
参数:无
返回:[{id, name, w, h, fmt, mips, array, size}, ...]

示例输出:

[
  {"id": 102757, "name": "RT_Color", "w": 1598, "h": 898, "fmt": "R8G8B8A8_UNORM", "mips": 1, "size": 5738408},
  {"id": 110432, "name": "eye_iris_d", "w": 512, "h": 512, "fmt": "BC3_UNORM", "mips": 10, "size": 349524}
]

get_buffers

列出所有缓冲区。

用法:get_buffers
参数:无
返回:[{id, name, length}, ...]

get_resources

列出所有资源(纹理、缓冲区、着色器、管线对象等)。

用法:get_resources
参数:无
返回:[{id, name, type}, ...]

get_texture_info

获取单个纹理的详细元数据。

用法:get_texture_info(resource_id)
参数:resource_id - 纹理资源 ID
返回:{id, name, w, h, d, fmt, mips, array, size}

🖼️ 类别七:纹理操作 (5个)

get_texture_data

获取纹理的像素数据(Base64 编码)。

用法:get_texture_data(resource_id, mip, slice)
参数:
  resource_id: int   纹理 ID
  mip: int = 0       Mip 级别
  slice: int = 0     数组切片
返回:{resourceId, length, base64: "...(前10000字符)"}

pick_pixel

读取纹理上指定坐标的像素值。

用法:pick_pixel(resource_id, x, y)
参数:
  resource_id: int   纹理 ID
  x: int             X 坐标
  y: int             Y 坐标
返回:{x, y, r, g, b, a}

使用场景:检查渲染目标上某个像素的颜色值,验证渲染结果。


get_texture_minmax

获取纹理中的最小/最大像素值。

用法:get_texture_minmax(resource_id)
参数:resource_id - 纹理 ID
返回:{min: {r, g, b, a}, max: {r, g, b, a}}

使用场景:检查 HDR 纹理的值域范围,判断是否有异常值。


save_texture

将纹理导出到磁盘。自动检测 CubeMap(arraysize=6)并适配导出。

用法:save_texture(resource_id, output_path, mip, slice)
参数:
  resource_id: int     纹理 ID
  output_path: str     输出文件路径
  mip: int = 0         Mip 级别
  slice: int = -1      CubeMap 面索引:-1=全部面(默认), 0-5=指定面
返回:
  2D 纹理:{saved: "path", type: "2D"}
  CubeMap PNG/JPG:{type: "cubemap", faces: 6, savedFaces: [...]}
  CubeMap DDS:{saved: "path", type: "cubemap", format: "DDS (all 6 faces)"}

支持格式:PNG, JPG, BMP, TGA, HDR, EXR, DDS(根据文件扩展名自动选择)

CubeMap 导出策略(v1.3.0 🆕):

格式 行为 文件
DDS 6 面合并为单文件 cubemap.dds
PNG/JPG/等 自动拆为 6 个面文件 cubemap_face0_posX.png ~ cubemap_face5_negZ.png
指定 slice=N 只导出第 N 面 cubemap.png(单文件)

面序:0=+X(右), 1=-X(左), 2=+Y(上), 3=-Y(下), 4=+Z(前), 5=-Z(后)

示例:

save_texture(102757, "C:/output/render_target.png")           # 2D 纹理
save_texture(98134, "C:/output/env_cubemap.dds")              # CubeMap → 1个DDS
save_texture(98134, "C:/output/env_cubemap.png")              # CubeMap → 6张PNG
save_texture(98134, "C:/output/env_front.png", slice=4)       # CubeMap → 仅+Z面

get_buffer_contents

读取缓冲区原始数据。

用法:get_buffer_contents(resource_id, offset, length)
参数:
  resource_id: int     缓冲区 ID
  offset: int = 0      起始偏移(字节)
  length: int = 256    读取长度(字节)
返回:{resourceId, offset, length, hex: "...", base64: "..."}

🔍 类别八:像素历史 (1个)

pixel_history

追踪一个像素在整帧内的完整修改历史。

用法:pixel_history(resource_id, x, y)
参数:
  resource_id: int   渲染目标纹理 ID
  x: int             像素 X 坐标
  y: int             像素 Y 坐标
返回:[{eventId, pre: {r,g,b,a}, post: {r,g,b,a}}, ...]

使用场景:调查某个像素为什么显示了错误的颜色。通过查看每次写入前后的值,可以定位到是哪个 DrawCall 导致了问题。

示例:

查看渲染目标 102757 上坐标 (400, 300) 的像素历史
→ pixel_history(102757, 400, 300)
→ 返回:[
    {eventId: 23, post: {r: 0.0, g: 0.0, b: 0.0, a: 0.0}},   // Clear
    {eventId: 73, post: {r: 0.8, g: 0.2, b: 0.1, a: 1.0}},   // 眼球渲染
    {eventId: 94, post: {r: 0.9, g: 0.7, b: 0.3, a: 1.0}},   // 特效叠加
  ]

🐛 类别九:着色器调试 (2个)

debug_pixel

逐步跟踪像素着色器的执行过程。

用法:debug_pixel(x, y)
参数:
  x: int   像素 X 坐标
  y: int   像素 Y 坐标
返回:{x, y, steps, trace: [{step, vars: [{name, val}]}, ...]}

⚠️ 需要先通过 get_pipeline_state 或 get_shader_info 设置当前事件。

使用场景:当着色器输出不正确时,逐步查看每个变量在执行过程中的值。


debug_vertex

逐步跟踪顶点着色器的执行过程。

用法:debug_vertex(vertex_id, instance_id)
参数:
  vertex_id: int       顶点 ID
  instance_id: int = 0 实例 ID
返回:{vertexId, steps, trace: [{step, vars}]}

⚡ 类别十:性能分析 (3个)

enumerate_counters

列出 GPU 支持的所有性能计数器。

用法:enumerate_counters
参数:无
返回:[{id, name, desc, unit}, ...]

fetch_counters

获取指定性能计数器的值。

用法:fetch_counters(counter_ids)
参数:counter_ids - 逗号分隔的计数器 ID 列表 (如 "1,2,3")
返回:[{eventId, counter, value}, ...]

get_action_timings

获取 DrawCall 的 GPU 耗时。

用法:get_action_timings(event_ids, marker_filter)
参数:
  event_ids: str = ""        逗号分隔的事件 ID (空=全部)
  marker_filter: str = ""    Marker 名称过滤
返回:计时数据

📐 类别十一:网格和调试 (3个)

get_post_vs_data

获取顶点着色器后的网格输出信息。

用法:get_post_vs_data
参数:无
返回:{numIndices, topology, indexStride, vertexStride}

get_debug_messages

获取图形驱动的验证/调试消息。

用法:get_debug_messages
参数:无
返回:[{eventId, severity, msg}, ...]

debug_vulkan_bindings 🆕

诊断工具:dump Vulkan descriptor set 绑定的原始数据结构,用于排查纹理绑定解析问题。

用法:debug_vulkan_bindings(event_id, stage)
参数:
  event_id: int   事件 ID
  stage: str      着色器阶段(默认 "fragment")
返回:{eventId, api, readOnlyResources, descriptorAccess, shaderReflection, ...}
超时:60 秒

用途:当 get_bound_textures 返回 resourceId=0 时,使用此工具诊断 Vulkan descriptor 的实际数据路径。

返回字段说明:

  • readOnlyResources — UsedDescriptor 对象列表(含 .descriptor.resource 实际纹理 ID)
  • descriptorAccess — DescriptorAccess 对象列表(含 descriptor store 和索引信息)
  • shaderReflection — Shader 反射中的只读资源绑定信息

📤 类别十二:导出 (2个)

export_drawcall

一键导出 DrawCall 的全部数据。

用法:export_drawcall(event_id, output_dir)
参数:
  event_id: int      事件 ID
  output_dir: str    输出目录
返回:{eventId, outputDir, files: [...]}
超时:60 秒

导出内容:

  • 所有格式的着色器反汇编 (.txt)
  • 嵌入源码 (如有)
  • 所有绑定纹理 (.png)
  • 常量缓冲区值
  • 管线状态摘要 (summary.json)

export_to_unity 🆕

一键将 DrawCall 导出为 Unity 可用资源(模型 + 材质映射)。

v1.5.0 改进:修复了多个模型导出质量问题——DX11 左手坐标系自动转换为右手坐标系、索引重映射精确提取、压缩编码法线自动检测。

纹理不在此工具导出——使用 save_texture 或 export_drawcall 单独导出纹理文件。 本工具返回的 textures 列表包含每张纹理的 resourceId,方便后续按需导出。

用法:export_to_unity(event_id, output_dir, mesh_name)
参数:
  event_id: int               事件 ID
  output_dir: str             输出目录
  mesh_name: str = "exported_mesh"  模型和材质名称
返回:{eventId, outputDir, meshFile, fbxFile, textures, materialFile, meshStats, files}
超时:60 秒

模型提取方式(v1.3.0 改进):

优先使用 VBuffer + IBuffer + VertexInputs 直接读取 GPU 缓冲区(参考 Model Extractor 插件), Vulkan/ANGLE 截帧兼容性远优于旧的 PostVS 方式。PostVS 作为回退方案保留。

支持的顶点格式:Float32、Float16、UNorm、SNorm、UInt、SInt。

导出内容:

文件 说明
{name}.obj 3D 模型 — OBJ 格式(顶点/法线/UV/索引)
{name}.fbx 🆕 3D 模型 — FBX 7.4 ASCII 格式(Unity/Unreal/Blender 通用)
{name}_material.json Unity 材质定义(Standard/URP/HDRP 属性映射)
{name}_UnityImport.cs C# 编辑器脚本(一键导入)
{name}_unity_export.json 完整导出摘要(含纹理绑定信息)

返回的纹理绑定信息(不导出文件):

"textures": [
  {
    "role": "albedo",
    "slot": 0,
    "resourceId": 268775,
    "width": 512, "height": 512,
    "hint": "Use save_texture(resource_id=268775, output_path=...) to export"
  }
]

Unity 导入流程:

  1. 复制导出文件夹(含 .fbx)到 Unity Assets/ 目录
  2. 用 save_texture 按 resourceId 导出所需纹理到同一目录
  3. 将 _UnityImport.cs 放入 Assets/Editor/
  4. 菜单 → RenderDoc > Import {name}
  5. 自动完成:导入模型 → 创建材质 → 赋贴图

🔍 类别十三:智能识别与分析 (2个)

identify_drawcalls 🆕

智能识别每个 DrawCall 的渲染内容(眼球、头发、铠甲、饰品等)。

核心原理:对每个 DrawCall 执行 SetFrameEvent → SaveTexture(RT),生成 RT 累积截图,直接"看到"每个 DrawCall 画了什么——比按面数猜测准确率高出一个数量级。

用法:identify_drawcalls(event_id_min, event_id_max, output_dir, render_target)
参数:
  event_id_min: int = 0          起始事件 ID
  event_id_max: int = 999999     结束事件 ID
  output_dir: str = ""           缩略图输出目录(每个 DrawCall 一张 RT 截图)
  render_target: int = 0         渲染目标 ID(0=自动检测)
返回:{renderTarget, rtSize, actionCount, shaderGroups, actions: [...]}
超时:120 秒

每个 DrawCall 返回的信息:

字段 说明
eventId 事件 ID
triangles 三角面数
vertexShader / fragmentShader Shader ID(同 shader = 同材质类型)
textureCount 绑定纹理数
textures 前 5 个纹理的 resourceId + 尺寸
screenBBox 屏幕空间包围盒(minX/Y, maxX/Y, depth)
screenCoverage 屏幕覆盖率百分比
thumbnail RT 累积截图路径(需指定 output_dir)

Shader 分组:自动按 VS/FS shader ID 分组,返回 shaderGroups:

{
  "110742/110743": [66],        // 皮肤 shader → EID 66
  "110755/110756": [73],        // 眼球 shader → EID 73
  "110759/110760": [87, 126],   // 头发 shader → EID 87, 126
  "106208/106209": [94,97,...],  // 饰品 shader → 8个实例
}

识别流程:

  1. 运行 identify_drawcalls 并指定 output_dir 保存缩略图
  2. 对比相邻截图(eid_NNNN.png),差异部分就是该 DrawCall 画的内容
  3. 结合 shaderGroups 分组——同 shader 的 DrawCall 是同类型部件

analyze_lighting 🆕

分析 DrawCall 的灯光设置——从 shader 代码和 constant buffer 中提取所有灯光相关信息。

用法:analyze_lighting(event_id)
参数:
  event_id: int   事件 ID
返回:{eventId, cbuffers, lightingModel, shadowMaps, environmentMaps}
超时:60 秒

分析内容:

维度 说明
光照模型检测 从 shader 反汇编中推断 PBR/Blinn-Phong/Lambert 等模型
Shader 特性 阴影映射、环境反射、次表面散射、多光源循环等
CBuffer 结构 所有 uniform 变量的名称、类型、数组大小
变量语义分类 自动将变量分为 light / shadow / ambient 类别
阴影贴图 识别绑定的 Depth 格式纹理(shadow map)
环境贴图 识别绑定的 CubeMap(IBL / 反射探针)

光照模型检测结果示例:

{
  "model": "PBR (inferred)",
  "features": [
    "shadow_mapping",
    "environment_reflection",
    "multi_light_loop"
  ]
}

CBuffer 变量自动分类(对 ANGLE 匿名变量的启发式规则):

数组模式 推断类别 说明
float4[4] ambient_or_matrix SH 系数或变换矩阵
float4[6] light_array 多光源数据(位置/颜色/方向/衰减)
float4[8] shadow_matrix 阴影级联矩阵
float4[2] shadow_param 阴影图集 UV 参数
单值(单位向量) light_direction 主光方向
单值(0~2 范围 RGB) color_or_light 灯光颜色

注意:Vulkan/ANGLE 截帧中 cbuffer 变量名为匿名(_childN),值需要通过 RenderDoc GUI 查看。 D3D11 截帧通常有完整的变量名和值。


第六章:实战工作流

6.1 工作流一:分析一个 DrawCall

目标:理解游戏中某个物体是怎么渲染的

Step 1: "列出所有 draw call"
        → get_draw_calls(only_actions=True)
        → 找到你感兴趣的 eventId (比如 73)

Step 2: "查看事件 73 的管线状态"
        → get_pipeline_state(73)
        → 确认使用了哪些 shader

Step 3: "逆向事件 73 的 fragment shader"
        → get_shader_info(73, "fragment")
        → 获取:反汇编代码 + 绑定纹理 + 常量缓冲区值

Step 4: "保存事件 73 的所有绑定纹理"
        → 对每个 boundTexture 调用 save_texture()

6.2 工作流二:定位渲染问题

目标:排查为什么某个像素显示了错误颜色

Step 1: "获取渲染目标信息"
        → get_textures() → 找到 RT 的 resourceId

Step 2: "查看像素 (400,300) 的修改历史"
        → pixel_history(rt_id, 400, 300)
        → 找到哪个 eventId 写入了错误值

Step 3: "分析那个 DrawCall 的 shader"
        → get_shader_info(event_id, "fragment")

Step 4: "调试那个像素"
        → debug_pixel(400, 300)
        → 逐步查看变量值

6.3 工作流三:导出到 Unity

目标:将截帧中的角色眼球导出到 Unity

Step 1: "列出 60-100 之间的 draw call"
        → get_draw_calls(event_id_min=60, event_id_max=100)
        → 找到眼球的 eventId (比如 73)

Step 2: "导出事件 73 到 Unity,命名为 eye_ball"
        → export_to_unity(73, "C:/output/eye", "eye_ball")
        → 生成 .obj + .png × N + material.json + UnityImport.cs

Step 3: 复制到 Unity 项目,运行导入脚本

6.4 工作流四:着色器逆向还原

目标:把截帧中的 shader 完整还原为可用的 .shader 文件

Step 1: "逆向事件 73 的 fragment shader"
        → reverse_shader(73, "fragment")
        → 获取 SPIR-V / HLSL 反汇编

Step 2: "逆向事件 73 的 vertex shader"
        → reverse_shader(73, "vertex")
        → 获取顶点着色器反汇编

Step 3: "获取事件 73 的所有绑定纹理和 cbuffer 值"
        → get_bound_textures(73, "fragment")
        → 获取纹理槽位映射

Step 4: "一键导出事件 73 的全部数据"
        → export_drawcall(73, "C:/output/shader_data")
        → 获取所有反汇编文件 + 纹理 + 参数

Step 5: 基于导出数据,让 AI 还原为完整的 Unity .shader 文件

6.5 工作流五:性能分析

目标:找到帧内最耗时的 DrawCall

Step 1: "列出所有可用的性能计数器"
        → enumerate_counters()
        → 找到 GPU Time 计数器的 ID

Step 2: "获取所有 DrawCall 的 GPU 耗时"
        → fetch_counters("1")  (假设 1 是 GPU Time)
        → 按耗时排序,找到瓶颈

Step 3: "分析耗时最高的 DrawCall"
        → get_shader_info(event_id, "fragment")
        → 查看 shader 复杂度

第七章:故障排除

7.1 连接问题

问题:ping 超时

✅ 检查清单:
1. RenderDoc (qrenderdoc.exe) 是否正在运行?
2. 截帧文件是否已加载?(标题栏显示文件名)
3. 扩展是否加载?
   → Tools > RenderDoc MCP > Status
   → 应显示 "MCP bridge is RUNNING"
4. IPC 目录是否可访问?
   → 检查 %TEMP%\renderdoc_mcp_ipc\ 是否存在

问题:扩展菜单不存在

✅ 检查清单:
1. 扩展文件路径是否正确?
   Windows: %APPDATA%\qrenderdoc\extensions\renderdoc_mcp\__init__.py
   Linux:   ~/.local/share/qrenderdoc/extensions/renderdoc_mcp/__init__.py
2. 文件名必须是 __init__.py,目录名必须是 renderdoc_mcp
3. 重启 RenderDoc
4. 查看 RenderDoc 的输出面板是否有错误信息

7.2 API 兼容性问题

问题:某些工具返回错误

不同版本的 RenderDoc 的 Python API 有差异。已知的兼容性处理:

问题 说明 解决方案
TextureDescription 无 name 旧版本不直接存名字 通过 GetResources() 查找
ResourceFormat str() 返回 Swig 对象 SWIG 包装问题 使用 .name 属性
SigParameter 无 compType Vulkan/ANGLE 截帧 getattr 安全访问
无 GetShaderPipelineObject 旧版 API Vulkan fallback
无 GetConstantBuffers/GetSamplers 版本差异 try/except 保护
UsedDescriptor 无 .resources 绑定结构变化 多种结构兼容
LoadCapture 需要 5 参数 新版 API 签名变化 try/except 自动适配 4/5 参数
Vulkan UsedDescriptor.resource 返回指针 SWIG 绑定差异 🆕 改用 .descriptor.resource 路径(v1.2.0 修复)

7.3 性能问题

问题:工具调用很慢

✅ 优化建议:
1. 避免频繁调用 get_textures() / get_resources() —— 结果不会变,缓存即可
2. export_drawcall 可能需要 30-60 秒 —— 它要遍历所有反汇编目标
3. pixel_history 在大尺寸 RT 上可能很慢 —— 这是 RenderDoc 本身的限制
4. 如果 IPC 超时,增加 timeout 参数

第八章:高级技巧

8.1 使用多个截帧

通过 list_captures + open_capture 可以切换不同截帧进行对比分析。

8.2 批量导出纹理

# 让 AI 执行:
"获取所有纹理列表,然后把所有大于 256x256 的纹理都导出为 PNG"
→ get_textures()
→ 对每个符合条件的纹理调用 save_texture()

8.3 Shader 对比分析

"比较事件 73 和事件 80 的 fragment shader 有什么区别"
→ get_shader_info(73, "fragment")
→ get_shader_info(80, "fragment")
→ AI 对比两个 shader 的差异

8.4 自定义 Unity 导入

export_to_unity 生成的 _material.json 包含三套属性映射:

  • property:Unity Standard Shader
  • urpProperty:URP (Universal Render Pipeline)
  • hdrpProperty:HDRP (High Definition Render Pipeline)

你可以手动编辑 JSON 来适配自定义 Shader。

8.5 IPC 调试

如果需要调试 IPC 通信,可以查看中间文件:

# 查看 IPC 目录
dir $env:TEMP\renderdoc_mcp_ipc\

# 查看最近的请求(如果有残留)
cat $env:TEMP\renderdoc_mcp_ipc\request.json

# 查看 RenderDoc 输出面板中的 [RD-MCP] 日志

附录A:API兼容性说明

本项目对以下 RenderDoc 版本进行了兼容性处理:

RenderDoc 版本 图形 API 测试状态
v1.26+ Vulkan (ANGLE/SPIR-V) ✅ 已测试通过
v1.26+ D3D11 (DXBC/ps_5_0) ✅ 已测试通过
v1.20+ D3D12 ⚠️ 兼容代码已就位(未实际测试)
v1.20+ OpenGL ⚠️ 兼容代码已就位(未实际测试)

D3D11 测试结果:

  • Pipeline state获取:✅ null pipeline ID fallback 生效
  • DXBC反汇编:✅ ps_5_0 正确反汇编
  • 输入/输出语义:✅ SV_Position/TEXCOORD/SV_Target/SV_IsFrontFace 正确解析
  • CBuffer变量:✅ 支持多CBuffer(含65KB动态索引cbuffer)
  • 纹理绑定:✅ SRV检测
  • Hull/Domain着色器:✅ 支持Tessellation阶段

Vulkan/ANGLE 和 D3D11 截帧已经过完整的兼容性测试和修复。

Vulkan 纹理导出修复(v1.2.0):

  • 问题:Vulkan 截帧中 get_bound_textures / export_drawcall 无法导出纹理(resourceId 全部返回 0)
  • 根因:UsedDescriptor 的 SWIG 绑定中,int(binding.resource) 返回内存指针而非 ResourceId
  • 修复:改用 binding.descriptor.resource 路径解析(UsedDescriptor → Descriptor → resource)
  • 验证:王者荣耀 Vulkan/ANGLE 截帧 → 9 张纹理全部成功导出为 PNG(含 Albedo/Normal/AO/Depth)

模型导出重写 + FBX 支持(v1.3.0):

  • 改进:参考 Model Extractor 插件,改用 GetVBuffers() + GetIBuffer() + GetVertexInputs() 直接读取 GPU 缓冲区
  • 优势:支持 Float16/Float32/UNorm/SNorm/UInt/SInt 顶点格式,Vulkan 兼容性远优于旧 PostVS 方式
  • 新增:FBX 7.4 ASCII 导出(_write_fbx_ascii),兼容 Unity/Unreal/Blender/Maya
  • 精简:export_to_unity 不再导出纹理 PNG(改用 save_texture / export_drawcall 单独导出),响应从超时 → 秒级完成
  • 验证:关羽头部 EID=172(2590 顶点/4772 面)→ OBJ 157.9KB + FBX 198.9KB — 两种格式同时生成 ✅

模型导出质量修复(v1.5.0):

  • 索引修复:正确应用 baseVertex(DrawIndexed 的 BaseVertexLocation)和 indexOffset(索引缓冲区偏移);引入索引重映射机制,只导出 DrawCall 实际引用的唯一顶点,杜绝多余顶点
  • 坐标系转换:DX11 左手坐标系 → 右手坐标系自动转换(位置 X 轴取负 + 三角面缠绕方向反转),解决模型镜像问题
  • 法线处理:自动检测压缩编码的 tangent frame(如 NORMAL 语义存 packed uint32),超出 [-1.5, 1.5] 范围的法线自动丢弃,让 Unity/Blender 根据面重算
  • UV 修复:flip_uv_v 默认关闭(DX11 → Unity 不需要翻转 V 坐标),避免 UV 上下颠倒
  • 顶点属性读取:始终按原始 compCount 读取再截取到 wanted_comp,避免 4 分量属性读 3 分量时的跨步对齐错误;分量不足时自动补零
  • 格式支持:新增 R10G10B10A2_UNorm/SNorm 打包格式解码
  • 验证:D3D11 抓帧 EID=320(3346 唯一顶点)→ OBJ + FBX 导出,UV/模型/法线在 Unity 中完全正确 ✅

附录B:已知限制

  1. find_by_shader 和 find_by_resource 在扩展端尚未完全实现
  2. get_action_timings 在扩展端没有对应处理函数
  3. 着色器调试(debug_pixel/debug_vertex)返回的步骤数限制为 50 步
  4. 纹理数据(get_texture_data)的 Base64 输出截断为前 10000 字符
  5. 缓冲区数据(get_buffer_data)最大读取 4096 字节
  6. 模型导出优先使用 VBuffer+IBuffer 方式(v1.3.0),PostVS 作为回退;FBX 导出为 ASCII 7.4 格式
  7. CubeMap 纹理导出已适配(v1.3.0):PNG/JPG 自动导出 6 面文件,DDS 导出完整 CubeMap
  8. 模型导出已包含 DX→右手坐标系自动转换(v1.5.0);压缩编码法线(packed tangent frame)会自动丢弃,由导入工具重算

附录C:文件结构参考

renderdoc-mcp/
├── pyproject.toml              # Python 项目配置
├── README.md                   # 英文文档
├── README_CN.md                # 中文概览
├── MANUAL_CN.md                # 本文件 - 完整手册
├── SETUP_GUIDE.md              # 安装配置报告
└── src/
    ├── __init__.py
    ├── server.py               # MCP Server (37 个工具)
    ├── rd_wrapper.py           # RenderDoc API 封装 (本地直连模式)
    └── ipc_client.py           # 文件 IPC 客户端

RenderDoc 扩展:
%APPDATA%/qrenderdoc/extensions/renderdoc_mcp/
    └── __init__.py             # 扩展端处理函数 (31 个方法)

IPC 通信目录:
%TEMP%/renderdoc_mcp_ipc/
    ├── request.json            # 请求文件 (临时)
    ├── ready                   # 就绪信号 (临时)
    └── response.json           # 响应文件 (临时)

手册版本: 1.5.0 | 最后更新: 2026-04-14

View this README on GitHub

安装

This server does not publish a one-line install command.

Open the repository installation guide