Ratty 是一个 GPU 加速渲染的终端模拟器,其核心创新在于将 3D 图形以内联方式嵌入终端缓冲区。与传统终端模拟器仅处理文本和 ANSI 转义序列不同,Ratty 构建了一套名为 Ratty Graphics Protocol(RGP)的通信协议,使得应用程序能够在终端单元格空间中注册、锚定和动画化 3D 资源。这一设计灵感源自 TempleOS 的 DolDoc 文档格式 —— 在该系统中,命令行动态包含精灵图和 3D 网格作为一等公民,而非孤立的多媒体附件。Ratty 采用 Rust 语言开发,底层渲染栈由 Ratatui(终端缓冲区建模)、Parley(文本塑形)、Vello(GPU 光栅化)和 Bevy(3D 场景管理)组成,通过分层架构将终端仿真与视觉呈现解耦。
渲染管线:五阶段流水线与数据跨域
Ratty 的渲染管线遵循严格的五阶段顺序:应用程序在 PTY 中运行并生成终端转义序列;vt100 解析器将这些序列转换为终端屏幕状态;Ratatui 根据该状态构建终端缓冲区并通过 parley_ratatui 在 GPU 上完成文本渲染;渲染结果以 RGBA 格式回读到 CPU 内存;最后 Bevy 将该纹理作为 3D 场景中的材质进行呈现。关键实现细节在于 Ratatui 将光标建模为一个普通的单元格位置,然后在 Bevy 侧独立创建一个 CursorModel 实体,通过计算单元格坐标到场景空间的映射来同步光标位置。具体映射公式为:cell_width = viewport_size.x / cols; cell_height = viewport_size.y / rows,再通过 x = -viewport_size.x * 0.5 + (cursor_col + 0.5) * cell_width 将终端坐标转换为 3D 空间位置。这种解耦设计使得光标可以独立于文本渲染进行动画 —— 例如配置旋转速度为 1.4 rad/s、上下浮动速度为 2.2 rad/s、浮动幅度为单元格高度的 15%。
当前管线的主要瓶颈在于第四阶段的 CPU 回读操作。Vello 在 GPU 上完成光栅化后,数据必须跨越设备边界回到主机内存,再复制到 Bevy 的纹理对象中。这一跨域传输引入了不可忽视的延迟开销,也意味着 Ratty 尚未实现真正的 GPU 共享纹理路径。如果未来要消除这一瓶颈,需要构建专门的 Bevy 渲染集成,直接在 Bevy 的渲染世界设备上渲染到 Bevy 自有纹理,而非经由 CPU 中转。这需要更深入的 wgpu/Bevy 内部 API 调用,但能将端到端延迟降低一个数量级。
RGP 协议:APC 承载的 3D 对象控制
Ratty Graphics Protocol 是整个内联 3D 功能的核心抽象层。协议消息通过 APC(Application Program Command)控制序列承载,格式为 ESC _ ratty;g;<verb> [; <key=value> ...] ESC \,其中 ratty 为协议命名空间、g 为图形子命名空间、<verb> 为操作动词。目前 RGP 定义了四个基本操作:支持查询(s)、资源注册(r)、对象放置(p)和对象删除(d)。
支持查询操作用于应用程序探测终端能力,响应参数包括协议版本(v)、支持的模型格式(fmt,值为 obj 或 glb)、路径注册(path)、动画支持(anim)、深度控制(depth)、颜色指定(color)和亮度调整(brightness)。资源注册操作用 r 动词,携带 id(对象标识符)、fmt(格式)和 path(模型路径)参数。对象放置操作用 p 动词,除了关联已注册资源的 id,还需指定锚点坐标 row 和 col、尺寸 w 和 h,以及可选的动画开关、缩放系数、深度偏移、颜色值和亮度值。深度参数控制对象在终端平面之下的距离,是实现分层效果的关键;颜色参数接受 RGB 十六进制格式如 7fd0ff。
RGP 的设计哲学强调终端单元格作为空间锚点的概念。当应用程序将 3D 模型放置在某单元格后,该单元格成为模型的附着点 —— 单元格移动时,模型随之移动,这与 TempleOS 的 DolDoc 内联精灵语义一致。为了简化应用程序集成,Ratty 提供了 ratatui-ratty crate,应用程序只需声明一个 RattyGraphic 对象并配置其参数,即可自动生成对应的 RGP 消息。Widget 层并不直接在终端缓冲区中绘制像素,而是向 stdout 写入 RGP 转义序列,由 Ratty 终端自行解析并渲染到 3D 场景中。
Cursor 配置参数与动画调优
对于需要定制 3D 光标场景的开发者,Ratty 在配置文件中暴露了完整的控制参数。模型相关参数包括:path 指定 OBJ 或 GLB 模型文件路径、scale_factor 相对于单元格尺寸的缩放倍数、brightness 材质亮度系数、x_offset 单元格内的水平偏移量(0.5 表示居中)、plane_offset 终端 3D 平面之外的推离距离。动画参数包括:spin_speed 绕 Y 轴的旋转角速度(单位应为 rad/s 量级)、bob_speed 上下浮动频率、bob_amplitude 浮动幅度占单元格高度的比例、visible 控制是否显示自定义光标模型。默认配置中旋转速度为 1.4、浮动速度为 2.2、浮动幅度为 0.08,可作为调参基准。
需要特别注意的是,plane_offset 在 3D 模式下尤为关键 —— 它控制光标与变形终端表面之间的距离。当用户使用 Ctrl+Alt+Up/Down 调整 warp 参数使终端表面发生透视变形时,过小的 plane_offset 会导致光标穿透终端平面而过犹不及;过大的值则使光标脱离终端主体,失去视觉关联性。建议在 2D 模式下设置较小的 plane_offset(如 10–15),在 3D warp 模式下增大至 20–25,以保持光标始终悬浮于终端表面之上。
资源开销与部署考量
Ratty 在设计上并非追求轻量 —— 它本质上是一个嵌入式游戏引擎(Bevy + wgpu)的终端模拟器外壳,因此资源消耗显著高于传统终端如 Alacritty 或 kitty。文档披露其内存占用通常超过 300MB,且首次编译需要拉取约 600 个 Rust 依赖项。对于日常开发场景,这一开销可能难以接受;但对于需要富媒体终端演示、交互式数据可视化或 Terminal Tuesdays 直播素材的场景,Ratty 提供了独特的能力组合。远程使用场景(如 SSH 连接)中 GPU 加速语义的传递需要额外考虑 —— 当前架构下所有 3D 渲染逻辑运行在本地 GPU 上,远程端仅传输终端文本流,这与图形协议如 Kitty Graphics 的工作方式类似。
资料来源:https://github.com/orhun/ratty、https://blog.orhun.dev/introducing-ratty/
内容声明:本文无广告投放、无付费植入。
如有事实性问题,欢迎发送勘误至 i@hotdrydog.com。