ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Bloodborne没有速度缓冲:bbport如何自算相机与对象运动向量?

Bloodborne没有速度缓冲:bbport如何自算相机与对象运动向量? Bloodborne没有速度缓冲bbport如何自算相机与对象运动向量【免费下载链接】bloodborne_pc项目地址: https://gitcode.com/gh_mirrors/bl/bloodborne_pcbbport 是一个让 PS4 版《Bloodborne》原生运行在 Linux PC 上的开源移植项目。由于游戏本身不输出速度缓冲velocity bufferbbport 自算运动向量先用深度和场景矩阵推导相机运动向量再从上一帧顶点位置计算对象运动向量配合抖动jitter与 FSR 时间性超分辨率让低分辨率渲染的画面在放大后依然清晰稳定。本文用通俗的方式讲清楚这套机制的原理、关键模块与验证方法。为什么《Bloodborne》需要自算运动向量时间性超采样TAA和 FSR 这类超分技术都依赖一个关键输入运动向量motion vectors——告诉 GPU 每个像素从上一帧移动到了这一帧的哪个位置。大多数 PC 游戏会直接渲染一张速度缓冲velocity buffer而《Bloodborne》在 PS4 上从未输出过速度缓冲连相机移动时也没有。bbport 在帧分析中确认了这一点docs/upscaler.md 明确指出 There is no velocity buffer。没有运动向量历史帧就无法正确重投影超分画面会糊成一片。所以 bbport 的选择是自己把运动向量算出来。整体思路相机向量打底对象向量精修bbport 把每个像素的运动向量分成两层来源来源覆盖范围计算方式 相机运动向量全场景默认兜底深度图 当前/上一帧相机矩阵 对象运动向量角色、武器、布料等动态物体对比上一帧保存的顶点位置最终合成规则很简单对象动了就用对象向量否则用相机向量。这套逻辑在合成着色器 camera_motion.comp 中完成——它会校验对象向量的深度是否与该像素当前深度一致防止被后续绘制的普通物体覆盖后用到过期向量不一致就退回相机向量。相机运动向量从深度和矩阵里还原位移《Bloodborne》每一帧都会把一组 864 字节的场景常量绑给几乎每个渲染通道其中包含视图矩阵view matrix唯一随相机变化的矩阵块投影参数垂直视野、近远裁剪面等分辨率签名例如[0]3000far 平面、[4]1920、[5]1080。bbport 靠这个签名识别场景常量并在 vk_camera_motion.h 的CameraMotion类中保存当前帧和上一帧两套相机参数。接下来是核心数学发生在 compute shader 里见 camera_motion.comp对每个像素读取深度值反推出它在视图空间的 3D 坐标用上一帧视图 × 当前视图逆矩阵把坐标变换回上一帧的相机视角再投影回屏幕得到该像素在上一帧的位置两者相减就是该像素的相机运动向量单位像素。一个易错细节被清除的深度天空代表无穷远方向旋转相机时要只旋转、不平移否则远处场景会剧烈抖动。bbport 在注释里专门记录了这一点。对象运动向量保存上一帧的顶点位置相机向量只能描述整个画面跟着相机走但角色挥刀、布料飘动这些物体自身的运动必须单独算。bbport 的方案记录在 docs/motion_vectors.md改写 G-buffer 顶点着色器在渲染角色、武器等动态物体时把每个顶点的裁剪空间坐标写进一块共享的历史缓冲跨帧匹配用一个包含顶点流、shader、索引内容哈希、顶点范围等字段的关键字把当前绘制和上一帧的绘制对上号像素着色器写差异当前位置减去上一帧位置得到该像素的对象运动向量兜底回退匹配失败或超出内存预算时自动退回相机向量画面不会崩。工程上的关键设计都集中在 motion_history.h 和 vk_object_motion.h只记录真正可能动的物体通过检查顶点着色器绑定的常量缓冲大小来分类——864 字节是场景常量相机≥640 字节是角色骨骼96~384 字节48 字节/根骨骼是小骨骼武器、道具。静态几何完全不占内存小骨骼门控武器每帧约有一千个小骨骼绘制大多是静止的。bbport 先用骨骼权重表bone palette的哈希做廉价比较哈希没变就跳过省下了大量开销预算与降级位置历史预算为每帧 4194304 个顶点两块缓冲共 128 MiB不够用时保留相机向量正确性防护原子写入防止同一顶点被多次绘制时竞态相机后面的位置和 NaN/Inf 向量直接作废。 一个真实的调试故事9 月 29 日玩家视频里回旋锯的锯盘旋转后拖着残影。日志显示锯盘只绑了 2~8 根骨骼96~384 字节被旧的≥640 字节阈值挡在外面只拿到了相机向量——对 FSR 来说它没动。把小骨骼纳入覆盖范围后残影消除。Jitter让每帧错开半像素光有运动向量还不够。时间性累积需要每一帧的采样点略有不同才能覆盖亚像素细节。bbport 用Halton(2,3) 抖动序列对场景几何做亚像素级的视口偏移Performance 档 32 个相位渲染分辨率降低如 960×540再由 FSR 3.1 / FSR 4 / FSR 4.1.1 重建到 1080p/1440p/4K 输出。运动向量计算时会先扣掉抖动偏移确保交给超分器的向量是无抖动的真实位移。如何验证与调试项目提供了不少验证手段对想深入了解的用户很友好BB_DEBUG_MOTION1把运动向量以颜色叠加到画面上还支持重投影上一帧 / 误差图模式——静态几何完全对得上说明相机向量正确单元测试 test_camera_motion.cpp 与 test_motion_history.cpp覆盖 u16/u32 索引、primitive restart、实例化、预算耗尽等边界情况test_motion_shaders.cpp用真实 SPIR-V 后端生成带/不带向量插桩的 shader 并通过spirv-val校验BB_OBJECT_MOTION0一键关闭对象运动功能做 A/B 对比。小结bbport 用深度 相机矩阵补齐了《Bloodborne》缺失的相机运动向量又用上一帧顶点位置历史 骨骼哈希门控算出对象运动向量两者合成后喂给 FSR 完成时间性超分。整个过程无需修改游戏逻辑只在渲染层完成——这也是它能在 RX 7800 XT 上跑到 4K 约 90 FPS、1440p 约 150 FPS 的关键之一。想了解更多设计细节可阅读超分器与帧分析docs/upscaler.md运动向量调优记录docs/motion_vectors.md深度自适应 TAA 实验docs/DEPTH_ADAPTIVE_TAA.md项目总览与构建方法README.md【免费下载链接】bloodborne_pc项目地址: https://gitcode.com/gh_mirrors/bl/bloodborne_pc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进