流式 SOG 格式
流式 SOG 将场景划分为多个细节层级的空间分块。查看器遍历空间树,决定当前相机所需分块与层级,使数千万高斯单元的大场景渐进加载并保持交互。
通过 SplatTransform 创建,步骤参见生成流式 SOG。每个分块都是标准 SOG。
本页是版本 1 格式规范。
1. 文件集合
数据集目录包含一个索引,每个分块各有一个子目录:
scene/
├── lod-meta.json # 索引:场景信息与空间树(本规范)
├── 0_0/ # LOD 0,分块 0,非打包 SOG(meta.json 与 .webp 纹理)
│ ├── meta.json
│ └── *.webp
├── 0_1/ # LOD 0,分块 1
├── 1_0/ # LOD 1,分块 0
├── … # 每个 {lod}_{chunk} 对应一个目录
└── env/ # 可选环境泼溅,非打包 SOG
- 索引必须名为
lod-meta.json,加载器通过名称识别格式。 - 每块是标准非打包 SOG v2 或 v3,包含 meta.json 与 WebP 纹理。单归档打包 SOG 分块不属于此格式。
- 全场景应用数据位于索引 extras,生产工具注释位于 comments;写入器不应在各分块 meta.json 重复。
- 索引 model 记录整场景训练方式,见 SOG §3.8。读取器应优先用于全部分块,缺失时才使用分块自身 model。
- 索引中全部路径相对于索引所在目录。
{lod}_{chunk}/ 目录名只是写入器惯例。读取器必须通过 filenames 数组解析位置,不能依赖命名模式。
2. lod-meta.json
interface LodMeta {
version: 1; // File format version (integer)
asset?: { // Optional tool/version metadata
generator?: string; // e.g. "splat-transform v2.5.2"
};
count: number; // Total gaussians across all LOD levels (excludes environment)
model?: "antialiased" | "2dgs"; // How the scene was trained, for all its chunks (see SOG §3.8); omitted for ordinary gaussians
counts: number[]; // Gaussians per LOD level; index = LOD level, length = lodLevels
lodLevels: number; // Number of LOD levels
lodErrors?: boolean; // Legacy (§3.3): if true, every leaf supplies per-level `errors`
environment?: string; // Relative path to the environment SOG's meta.json; omitted if none
filenames: string[]; // Relative paths to chunk SOG meta.json files, referenced by index
tree: Node; // Root of the spatial tree
extras?: any; // Application-defined JSON for the whole scene (see SOG §4); only with SOG version 3 chunks
comments?: string[]; // Free-form producer comments for the whole scene (see SOG §5); only with SOG version 3 chunks
}
interface Node {
bound: {
min: [number, number, number]; // AABB minimum [x, y, z]
max: [number, number, number]; // AABB maximum [x, y, z]
};
children?: [Node, Node]; // Interior node: exactly two child nodes
lods?: {
[lodLevel: string]: { // Leaf node: map of LOD level → splat range
file: number; // Index into filenames
offset: number; // Index of the first splat within the chunk
count: number; // Number of consecutive splats
};
};
errors?: number[]; // Legacy (§3.3), leaf node: per-level approximation error; index = LOD level
}
3. 空间树
tree 是场景的二叉空间划分。每节点有轴对齐包围盒,要么是有且恰有两个 children 的内部节点,要么是有 lods 的叶节点,不能同时为两者。
- 叶节点 bound 包含所有所属单元的完整范围:中心按旋转缩放后的椭球扩展,不仅是中心点。
- 内部节点 bound 是子边界并集。
- 边界与分块内位置使用同一坐标系。
3.1 LOD 层级
层级 0 细节最高,数字越大越粗。叶节点 lods 以层级的十进制字符串为键,从 "0" 到 "lodLevels - 1"。缺键表示该层级无数据。
叶节点所有 LOD 覆盖同一区域,查看器根据距离等条件为每个叶节点恰选一个层级。
3.2 分块引用
每个 lods 条目指向单一分块中的连续数据段:
- file 是顶层 filenames 数组的索引。
- offset 和 count 按存储顺序选择
[offset, offset + count),单位为单元索引而非字节。SOG 纹理采用像素行优先顺序,单元 i 位于(i % W, floor(i / W))。
分块内容恰为引用它的叶节点数据段串联,各段不重叠且完整覆盖分块。段内按 Morton 顺序排列以保持空间局部性,跨段无顺序保证。每块仅包含同一 LOD。
3.3 LOD 误差(旧版)
顶层 lodErrors 为 true 时,每叶有按层级索引的 errors 数组,衡量相对最高细节的偏差。值有限、非负、随层级不减,0 层通常为 0。只有相对大小有意义,可判断哪些区域最值得加载精细层。PlayCanvas 按相机距离选 LOD,不读取误差;叶节点不存在的层级条目会被忽略。
SplatTransform 3.3–3.7 写入这些值,3.8 起省略。读取器应将没有 lodErrors: true 的索引视为无误差数据,采用自身策略,例如根据各层单元数推导。
4. 环境
可选 environment 指向标准非打包 SOG,保存不参与 LOD 分块流式加载的单元,通常为天空等远景。查看器应独立于空间树无条件加载渲染。
5. 精度
索引自有字段的非整数值量化为 7 位有效数字,约等于 32 位浮点精度。extras 属应用数据,原样写入。
6. lod-meta.json 示例
带环境的双层场景,一个内部节点及两个叶节点:
{
"version": 1,
"asset": { "generator": "splat-transform v2.5.2" },
"count": 1500000,
"counts": [1000000, 500000],
"lodLevels": 2,
"environment": "env/meta.json",
"filenames": [
"0_0/meta.json",
"1_0/meta.json"
],
"tree": {
"bound": { "min": [-10, 0, -10], "max": [10, 5, 10] },
"children": [
{
"bound": { "min": [-10, 0, -10], "max": [0.5, 5, 10] },
"lods": {
"0": { "file": 0, "offset": 0, "count": 600000 },
"1": { "file": 1, "offset": 0, "count": 300000 }
}
},
{
"bound": { "min": [0.5, 0, -10], "max": [10, 4.5, 10] },
"lods": {
"0": { "file": 0, "offset": 600000, "count": 400000 },
"1": { "file": 1, "offset": 300000, "count": 200000 }
}
}
]
}
}
7. 版本与兼容
- 本规范文件的 version 为 1,读取器应拒绝更高主版本。
- 版本化之前的文件省略 version、asset、count、counts,可能包含
"environment": null。兼容它们时,应将缺失版本视为预发布,null 视为无环境。 - 应忽略未知字段,让小幅增量扩展无需提升版本。