逆向工程师的读心术:从着色器常量定位抗锯齿与帧生成挂载点
逆向工程师的读心术从着色器常量定位抗锯齿与帧生成挂载点【免费下载链接】uncharted_pcUncharted: The Nathan Drake Collection running natively on Windows - by SuperMedo项目地址: https://gitcode.com/gh_mirrors/un/uncharted_pc拿到一份没有源码的 PS4 游戏二进制想给它塞进现代画质技术——时序抗锯齿TAA/FSR/DLSS、帧生成FSR 3.1 FG / DLSS FG——第一道坎不是算法难而是往哪儿插。游戏是自己的渲染循环后处理、色调映射、UI 一层层叠在场景颜色之上插早了HUD 和特效会进历史缓冲插晚了拿不到线性 HDR 场景颜色与深度。本文以uncharted_pc《神秘海域德雷克合集》Windows 原生移植由 SuperMedo 发起为例拆解它如何仅靠逐帧解析游戏着色器绑定的常量缓冲在没有源码的情况下读心出三个关键挂载点相机速度通道、场景颜色之后的第一个计算通道、以及 UI 绘制前的显示缓冲写入通道。源码不可得的困境挂载点为什么难找PS4 游戏的 eboot 是 x86-64 二进制图形指令走 GNM 命令流着色器以二进制 IR 形式被打包。移植项目uncharted_pc的路径是让原版可执行文件直接跑在 Windows 上用 shadPS4 的视频核心与着色器重编译器把 GNM 翻译成 Vulkan详见 ROADMAP.md。这一步只解决了画得出来没解决在哪里动手脚。时序类画质技术的共同输入需求是苛刻的场景颜色必须是线性 HDR、且在游戏后处理bloom、色彩分级之前拿到否则颜色重建无从谈起深度必须是对应当前帧相机的那张场景深度运动向量要表达上一帧到这一帧的像素位移且必须排除 jitter 抖动本身的贡献UI 分离插帧与历史累积都不能把 HUD 算进去否则菜单会拖影、小地图会糊。游戏内显然没有这些语义标记。你能看到的只有一条 draw 命令、一个绑定的常量缓冲、一组目标和一组着色器哈希。所以问题转化为如何在成百上千个 draw/dispatch 中认出这就是场景颜色之后的第一个计算通道逐帧解析常量缓冲签名匹配项目的第一层答案是帧分析器frame analyzer。在 vk_frame_capture.cpp 中BB_CAPTURE_TRIGGERfile触发下一帧的完整记录每个 pass 的绘制次数、颜色/深度目标、采样的纹理、vs/ps/cs 哈希以及对小型全屏 pass 和每个几何 pass 的第一个 draw记录绑定常量缓冲的前 1 KiBBuffer 函数void FrameCapture::Buffer(u64 stage_hash, u32 slot, VAddr address, const void* data, u64 size) { const u64 bytes std::minu64(size, 1024) ~u64(3); ... }这一转储 对三作共用后处理的分析见 upscaler.md得到了三个以着色器哈希为键、常量缓冲为证的挂载点最终固化在 run.py 的默认环境变量里环境变量值语义BB_VELOCITY_PSf4b18264运动模糊的相机速度通道全屏960×540它的常量缓冲直接给出相机BB_UPSCALE_BEFORE_CSaec539f0光照场景颜色之后的第一个计算通道DLSS/FSR/TAA 在它之前运行帧生成在这里取深度与运动BB_HUDLESS_PS484cdbf5写入显示缓冲、UI 之前的第一个 draw其目标即无 UI 的画面这三者构成了读心的核心哈希是钥匙常量是密码本。从常量反推相机逆向数学还原有了目标 pass第二层是读懂常量缓冲本身。对三作共享的运动模糊速度通道其像素着色器 IR 转储暴露了相机重构公式注释直接写在 vk_camera_motion.cppz c9 / (depth - c8), view (z (c0 u c2), z (c1 v c3), z) p M view t (M, t: rows c12..c23) previous clip x, y, w rows c40..c43, c44..c47, c52..c55 of (p, 1)运行时钩子OnVelocityConstants做的就是把这套布局翻译成结构化的相机对象——从常量矩阵算出到上一帧裁剪空间的重投影矩阵to_previous_clip、UV 到视图的映射uv_to_view和深度到 z 的映射depth_to_zOnVelocityConstantscamera.uv_to_view {c[0], c[1], c[2], c[3]}; camera.depth_to_z {c[8], c[9]};而这条 hook 的触发点选得极巧在光栅化器的 draw 提交处按像素着色器哈希命中才读取常量vk_rasterizer.cppif (ps camera_motion-IsVelocityShader(ps-pgm_hash) !ps-buffers.empty() !ps-buffers[0].IsSpecial()) { ... camera_motion-OnVelocityConstants( reinterpret_castconst float*(sharp.base_address), bytes / sizeof(float)); }有了相机camera_motion.compcamera_motion.comp在 mode 2 下重放这套数学用深度重建视图空间位置、用重投影矩阵映射回上一帧 UV得到像素级、上一帧减当前帧的运动向量写入 RG16F 目标。这正是 FSR/DLSS/TAA 与帧生成共享的运动输入。逐帧签名场景常量作为路标另一种情况不需要先识别 pass——游戏每帧都有个 864 字节的场景常量块几乎所有 pass 都会绑定它。它的特征极其稳定[0]3000 (far)、[1]1/3000、[4]1920、[5]1080。OnConstants用这一签名做过滤命中后只取每帧第一个相机frame_has_camera保证提取视图矩阵、逆视图与投影参数OnConstantsif (data[0] ! 3000.0f || data[4] 64.0f || data[5] 64.0f || std::abs(data[1] * data[0] - 1.0f) 1e-3f) { return; } ... std::memcpy(current.view.data(), data 8, 12 * sizeof(float)); std::memcpy(current.inv_view.data(), data 180, 12 * sizeof(float)); current.proj {data[52], data[57], data[62], data[63]};这套签名匹配的思路同样被用在对象运动向量上G-buffer 顶点着色器的常量缓冲按大小分类——864 字节是场景相机块≥640 字节是角色骨骼96~384 且是 48 的倍数是小骨骼武器/道具见 motion_history.h 的ClassifyBuffer。于是哪个 draw 在画角色、哪个在画静态地图无需游戏源码即可判定只有骨骼网格才走昂贵的顶点历史重放静态网格继续用廉价相机向量——这也是从 49 FPS 提到 80 FPS 的路径之一详见 motion_vectors.md。挂载点汇合一次 dispatch 触发整套时序管线最后所有线索在OnDispatch汇合vk_temporal_upscaler.cpp计算着色器哈希等于BB_UPSCALE_BEFORE_CS时先为帧生成抓取深度与运动CaptureFrameGen与升采样器共用同一套速度通道相机再运行升采样器void TemporalUpscaler::OnDispatch(u64 cs_hash) { if (cs_hash ! trigger_hash || done_this_frame) return; if (frame_generator frame_generator-Wanted() camera_motion.VelocityMode() !frame_gen_captured) { frame_gen_captured true; CaptureFrameGen(); } ... Run(); }帧生成端vk_frame_generation.h随后在BB_HUDLESS_PS命中时抓取无 UI 帧FSR 3.1 帧插值把两帧游戏画面之间的中间帧算出来frame_gen_ui.comp再把当前帧的 UI 盖回生成帧上DLSS FG 则把无 UI 帧作为 HUD-less 输入。这套常量 → 相机 → 运动向量 → 挂载的链路构成了 60 FPS 插到 120/240 FPS 的完整底座。方法论可复用的移植工具箱这套读心术不绑定《神秘海域》可以抽象成可复用的步骤建帧分析器记录 pass 的目标、着色器哈希、绑定常量前 1 KiB——BB_CAPTURE_TRIGGER/BB_CAPTURE_DIR即为此设计配合tools/drive.py的shot可脚本化抓帧找签名常量块全屏 pass 的常量缓冲通常含远平面/1-远平面/渲染尺寸这类稳定路标用签名过滤即可锁定每帧相机哈希定位挂载点把场景颜色后的第一个 compute、UI 前第一个 draw等语义锚定到具体的 cs/ps 哈希暴露为环境变量如BB_VELOCITY_PS、BB_UPSCALE_BEFORE_CS、BB_HUDLESS_PS重放数学而非逆向逻辑从着色器 IR 转储里读出矩阵布局在宿主侧用同样的公式重建运动向量而不去逐条模拟游戏代码。这套方法对任何无源码 有渲染管线的移植场景都成立——shadPS4 系的血源移植本仓库的姊妹工程文档同源正是同一批代码、同一套签名字段在服务。反过来也提醒移植者给未来留语义标记环境变量 哈希白名单是把逆向偶然性变成工程确定性的关键。下一次再遇到往哪儿插 TAA的问题答案不是猜而是读——读那一帧的常量缓冲游戏会自己告诉你它把相机藏在了哪里。【免费下载链接】uncharted_pcUncharted: The Nathan Drake Collection running natively on Windows - by SuperMedo项目地址: https://gitcode.com/gh_mirrors/un/uncharted_pc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Cache 一致性实战:一个由 Cache Line 对齐引发的血案

Cache 一致性实战:一个由 Cache Line 对齐引发的血案

摘要: 在多核异构 SoC(Cortex-A7 + Cortex-M4)上跑 RTOS,共享内存区偶尔读到"过去的数据",甚至在数据明明已经更新后仍读到旧值。这类问题通常在实验室难以复现,量产阶段才爆发。本文用一个真实的工业网关事故,从现象到根因,拆解 Cache 一致性问题的三种典型…

2026/10/18 15:07:56 阅读更多 →
Ling-3.0-tiny-singprobe核心组件解析:MLP探针与注意力探针的设计取舍

Ling-3.0-tiny-singprobe核心组件解析:MLP探针与注意力探针的设计取舍

【免费下载链接】Ling-3.0-tiny-singprobe 项目地址: https://ai.gitcode.com/hf_mirrors/inclusionAI/Ling-3.0-tiny-singprobe 点击查看 免费下载 SingProbe(Ling-3.0-tiny-singprobe)是基于 Ling-3.0-tiny 基座模型构建的内生式流式安全护…

2026/10/18 15:07:56 阅读更多 →
OpenAI Codex CLI 实战:用 TaoToken 统一 Key 打通 Node.js 自动化项目工作流

OpenAI Codex CLI 实战:用 TaoToken 统一 Key 打通 Node.js 自动化项目工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 15:06:56 阅读更多 →

最新新闻

Android自定义View实现A-Z字母导航栏:触摸事件与列表联动全解析

Android自定义View实现A-Z字母导航栏:触摸事件与列表联动全解析

简介:面向Android应用开发者的自定义View实现资料,围绕字母导航栏(AlphabetNavigationBar)这一典型交互组件,讲解从布局设计、字母按钮生成、点击事件监听,到与ListView/RecyclerView联动滚动的完整实现思路…

2026/10/18 16:02:20 阅读更多 →
Back to the Basics: Rethinking Issue-Commit Linking with LLM-Assisted Retrieval

Back to the Basics: Rethinking Issue-Commit Linking with LLM-Assisted Retrieval

文章主要内容和创新点 主要内容 本文聚焦于软件维护中的问题-提交关联(issue-commit linking) 任务,即建立bug报告等问题与修复它们的代码提交之间的关联。现有方法在评估时存在局限性:评估数据集的虚假链接分布不真实(如虚假链接数量与真实链接接近,或时间窗口过窄),…

2026/10/18 16:02:20 阅读更多 →
Android健身房助手:Kotlin+Compose+Room构建记录系统

Android健身房助手:Kotlin+Compose+Room构建记录系统

开头写得有吸引力一点,然后开始各个章节。每个H2/H3编号正确。代码块标注语言类型。不用mermaid,不用emoji。我先草拟全文,确保字数足够。开头(约300字):健身的人真正缺的,不是“下一个动作怎么…

2026/10/18 16:02:20 阅读更多 →
黄白助手 第 042 个开关:启用已读会话的位置、验证方法与风险边界

黄白助手 第 042 个开关:启用已读会话的位置、验证方法与风险边界

🔥 个人主页: 杨利杰YJlio ❄️ 个人专栏: 《Windows 疑难杂症与工单复盘案例库》 《Sysinternals实战教程》 《WINDOWS教程》 《Windows PowerShell 实战》 《IOS插件分析测试》 《超简单:用Python让Excel飞起来》…

2026/10/18 16:02:20 阅读更多 →
移动端适配全攻略:从viewport到vw、安全区与高清屏的实战指南

移动端适配全攻略:从viewport到vw、安全区与高清屏的实战指南

接手一个移动端活动页,设计稿明明是按750宽出的,一上真机,左边机型字体大了一圈,右边机型底部按钮被虚拟按键挡住,中间还有个别安卓机页面整个横向飘出去了。这种场景做移动端的兄弟应该都不陌生。移动端适配这事儿&am…

2026/10/18 16:02:20 阅读更多 →
代数数论入门:从理想分解到类群与单位定理的实践指南

代数数论入门:从理想分解到类群与单位定理的实践指南

简介:这是一部代数数论领域公认的经典教材,作者为德国数学家尤尔根诺伊基希,由诺伯特夏帕赫尔译成英文,德语原版1992年出版,英译本1999年列入施普林格“数学基础”系列。全书从整数、有理数、代数整数与有限域等基本对…

2026/10/18 16:01:19 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →