
推荐大家体验用AI编程,人工智能学习小站如下,已整理好相应高质量资源:
前言 -- 人工智能学习网
原文发表于2026年7月。作者以第一人称视角,完整记录从3D Gaussian Splatting技术原理研究,到HarmonyOS 7端侧重建API深入探索,再到ArkTS应用工程落地的全过程。
一、缘起:一部手机,一座祠堂
我的老家在皖南一座小镇上。镇口的李氏宗祠有三百多年历史,飞檐翘角、雕梁画栋,是我们这一代人共同的记忆锚点。但每次离家,那座祠堂就在记忆里慢慢模糊了------模糊了飞檐的弧度,模糊了砖墙斑驳的纹理,模糊了穿过月洞门时那一瞬的天光。
我一直在想:有没有一种技术,能让普通人只用手机,就把身边的历史文化遗产变成可以触摸、可以漫游、可以传承的数字资产?
HarmonyOS 7 (API 26) 给出的答案是 3DGS 端侧重建。这项技术让原本需要专业激光扫描仪和云端工作站的三维重建,如今只需一部手机的算力,在端侧即可完成。从「拍几张照片」到「生成可漫游的 3D 高斯溅射模型」,全链路都可以在用户手中完成,数据不出设备,安全可控。
于是,我启动了这个工程:古韵新生(HeritageGuardian)------一个基于 ArkTS + HarmonyOS Stage 模型的文化遗产数字守护 App。
二、3D Gaussian Splatting 技术原理:为什么它能跑在手机上?
在动手写代码之前,我先花了一周时间深入理解 3DGS 的底层原理。NeRF 用隐式神经辐射场惊艳了世界,但它需要逐像素光线步进(volumetric ray marching),计算开销巨大,很难在移动端实时渲染。3DGS 则用了一套截然不同的思路:显式高斯椭球体 + 可微分光栅化。
2.1 高斯溅射表示(Gaussian Splatting Representation)
3DGS 用数百万个可学习的 3D 高斯椭球体来显式地表示场景。每个高斯包含四个核心属性:
| 属性 | 含义 | 存储开销 |
|---|---|---|
位置 position |
三维空间坐标 (x, y, z) | 3 floats |
协方差矩阵 covariance |
控制椭球的形状、大小和方向 | 3 + 4 floats |
不透明度 opacity |
该高斯的透明度 α | 1 float |
球谐系数 Spherical Harmonics |
视角相关的颜色(支持多视角光照变化) | (1+deg)^2 * 3 |
与 NeRF 的隐式坐标-颜色映射不同,3DGS 的这些参数直接存储在显存中,渲染时不需要神经网络推理------渲染速度的核心瓶颈被消除了。
2.2 可微分渲染训练流程
训练过程本质上是一个光栅化的可微分管道:
1. 预处理:将 3D 高斯投影到屏幕空间,计算 2D 协方差
2. Tile 分配:根据包围盒将高斯分配到对应的屏幕 Tile
3. 深度排序:按深度从前到后排序,保证 alpha blending 正确
4. 光栅化:逐个高斯进行 alpha blending,计算最终像素颜色
5. 反向传播:将渲染结果与真实照片比较,梯度回传优化高斯参数
关键点在于第4步------它不是光线步进,而是直接在屏幕上"画"高斯。每个高斯在屏幕上的投影是一个 2D 椭圆,这些椭圆的 alpha blending 过程天然适合 GPU 并行化。
2.3 为什么 3DGS 特别适合移动端?
| 特性 | NeRF | 3DGS |
|---|---|---|
| 渲染方式 | 逐像素光线步进(耗时) | 高斯基元直接光栅化(快速) |
| 表示方式 | 隐式 MLP(需推理) | 显式存储(直接读取) |
| GPU 并行 | 较差(每条光线独立计算) | 优秀(Tile 内高斯可并行) |
| 存储压缩 | 较小(仅网络参数) | 可量化/蒸馏压缩至数 MB |
| 端侧可行性 | 极低 | 高(已有 1000+ FPS 方案) |
2026 年最前沿的 Mobile-GS 工作已经能在移动端实现 1098 FPS 的无界场景渲染,存储压缩至 4.8 MB。这为 3DGS 在 HarmonyOS 手机上的落地扫清了最大的性能障碍。
三、HarmonyOS 7 空间建模服务全景
HarmonyOS 7 在 API 26 中将 3DGS 能力封装为 Spatial Recon Kit,提供三大模块,覆盖了从重建到渲染到编辑的完整链路:
Spatial Recon Kit
├── spatialImage → 2D图像 → 3DGS/Mesh 模型(端侧重建)
├── spatialRender → 3DGS模型加载、实时渲染、滤镜效果
└── spatialEdit → 3DGS模型选择、上色、删除、导出PLY
这三个模块分别对应 @kit.SpatialReconKit 的三个命名空间,配合 @kit.ArkGraphics3D 的 Scene/Node/Camera 体系,构成了端侧空间计算的完整技术栈。
3.1 spatialImage:端侧重建的核心引擎
spatialImage.SpatialImageGenerator 是端侧重建的入口。它的调用链非常清晰:
typescript
// 1. 检查设备是否支持
let status = spatialImage.SpatialImageGenerator.isSupport();
// STATUS_SUCCESS → 支持且模型就绪
// STATUS_AIMODEL_NOT_EXIST → 支持但需下载模型
// STATUS_NOT_SUPPORT → 设备不支持
// 2. 下载 AI 重建模型(需 ohos.permission.INTERNET)
await generator.prepareEnv((progress: number) => {
console.log(`模型下载进度: ${progress}%`);
});
// 3. 从 2D 图像生成 3DGS 模型
let ret = await generator.generate(
pixelMap, // 输入图像
spatialImage.SpatialImageModelType.MODELTYPE_GS, // 高斯溅射
'/data/storage/.../model.ply' // 输出路径
);
注意几个细节:
isSupport()是同步静态方法 ,返回SpatialImageStatus状态码。这意味着你可以在应用启动时就快速判断设备能力,决定是否展示重建入口。prepareEnv()的回调参数是0~100的整数进度,而generate()本身不提供进度回调,需要应用层自行设计进度反馈。- 同一时间仅支持一个任务,需等待前一个任务完成后才能发起新任务。
3.2 spatialRender:加载并渲染高斯溅射场景
渲染端需要先加载 3DGS 插件,再加载模型节点:
typescript
// 必须先加载插件,否则 GSPlugin 接口行为未定义
renderContext.loadPlugin(spatialRender.GSPlugin.PLUGIN_ID);
// 加载模型到场景根节点
let settings: spatialRender.GSImportSettings = {
uri: 'OhosRawFile://assets/models/heritage.ply',
offset: 0
};
let gsNode = await spatialRender.GSPlugin.loadGSNode(scene, settings, scene.root);
gsNode.position = { x: 0, y: 0, z: 0 };
gsNode.scale = { x: 1.5, y: 1.5, z: 1.5 };
GSNode 继承自 Node,因此可以使用 position、scale、rotation、visible 等标准节点属性。旋转使用四元数表示,避免了欧拉角的万向锁问题。
spatialRender 还内置了四种滤镜效果:复古(RetroEffect)、漫画(ComicEffect)、黑白 Bit(ObraDinnEffect)、颜色编辑(ColorEditingEffect)。这些效果通过 camera.effects.append(effect) 添加到相机效果链,非常自然地融入了 ArkGraphics 3D 的渲染管线。
3.3 spatialEdit:直接在端侧修复文物模型
这是 API 26 新增的能力,支持对 3DGS 模型进行直接编辑:
typescript
let editor = spatialEdit.GSEdit.editGSNode(gsNode);
// 2D 矩形区域选择(视口归一化坐标 0~1)
editor.selectBy2DBox({ x: 0.25, y: 0.25, width: 0.5, height: 0.5 });
// 上色修复(Color 分量范围为 0~1)
editor.paint({ r: 0.72, g: 0.53, b: 0.27, a: 0.78 }, spatialEdit.PaintMode.MULTIPLY);
// 删除残损区域
editor.remove();
// 撤销
editor.undo();
// 保存修复副本为 PLY
await editor.saveToPLY('/data/storage/.../restored.ply');
这个编辑能力的设计非常巧妙。3DGS 的「选区」本质上是选取视口区域内的高斯椭球体,而不是网格面片。MULTIPLY 混合模式将新颜色与原颜色相乘,比 REPLACE 更自然地模拟了文物补色效果。撤销操作是线性历史栈,支持连续撤销。
四、ArkTS 工程架构:三层服务化设计
我采用 三层服务化架构 来组织整个工程,共 24 个源文件:
HeritageGuardian/
├── AppScope/app.json5
└── entry/src/main/
├── module.json5 # 权限声明
├── resources/
└── ets/
├── entryability/EntryAbility.ets
├── common/
│ ├── Logger.ets # hilog 封装
│ └── Constants.ets # 常量与阶段枚举
├── model/
│ ├── HeritageModel.ets # 数据模型与示例数据
│ └── AppRouter.ets # 路由工具
├── service/ # 8 个服务单例 ← 核心
│ ├── SpatialReconService.ets # 端侧重建
│ ├── SpatialRenderService.ets # 3DGS渲染
│ ├── SpatialEditService.ets # 模型编辑修复
│ ├── CameraService.ets # 相机采集
│ ├── FileStorageService.ets # 文件存储
│ ├── SensorService.ets # 陀螺仪
│ ├── AREngineService.ets # AR引擎
│ └── DistributedService.ets # 分布式流转
├── components/
│ ├── HeritageCard.ets # 遗产卡片
│ └── ScanProgress.ets # 重建进度环
└── pages/
├── Index.ets # 首页
├── CapturePage.ets # 采集页
├── ReconstructPage.ets # 重建页(核心)
├── RoamPage.ets # AR漫游页(情感核心)
├── ArchivePage.ets # 档案管理页
└── EditPage.ets # AI风貌修复页
4.1 基础设施层
- Logger :基于
@kit.PerformanceAnalysisKit的 hilog 封装,统一日志域名0xA001,支持 info/error/debug/warn 四级。 - Constants :定义重建阶段枚举(
STAGE_CHECK/STAGE_DOWNLOAD/STAGE_POINTCLOUD/STAGE_OPTIMIZE/STAGE_DONE)、应用名称、存储目录等。 - HeritageModel :数据模型定义,包含
HeritageItem(遗产项)、CaptureImage(采集图像)、ReconstructProgress(重建进度)、ARPoiInfo(AR兴趣点)。预置三条示例数据:李氏宗祠(清乾隆)、镇远古桥(明万历)、文庙大成殿(清光绪)。 - FileStorageService :文件存储单例,管理应用沙箱内的图片、模型、元数据文件读写。使用
@ohos.file.fs的同步接口(openSync/readSync/writeSync),适合端侧 I/O 场景。 - CameraService :基于
@kit.CameraKit封装相机采集流程,包括权限申请、相机打开、拍照回调、资源释放。
4.2 空间服务层
这是整个工程的技术核心,8 个服务单例全部使用 private constructor + static getInstance() 单例模式,确保全局唯一实例。
| 服务 | 依赖 Kit | 核心职责 |
|---|---|---|
SpatialReconService |
@kit.SpatialReconKit (spatialImage) |
设备支持检测、AI模型下载、2D→3DGS重建、多图重建调度 |
SpatialRenderService |
@kit.SpatialReconKit (spatialRender) + @kit.ArkGraphics3D |
3DGS插件加载、模型加载、变换、复古/漫画滤镜、相机管理、漫游旋转 |
SpatialEditService |
@kit.SpatialReconKit (spatialEdit) + @kit.ArkGraphics3D |
2D/3D选区、上色修复、删除、撤销、批量风貌修复、PLY导出 |
SensorService |
@kit.SensorServiceKit |
陀螺仪监听启动/停止 |
AREngineService |
@kit.AREngine |
AR会话创建、平面检测、锚点放置、帧回调 |
DistributedService |
@ohos.data.distributedData |
KV存储、跨设备元数据同步、模型URI分享 |
4.3 UI 层
6 个页面通过 @Entry @Component 声明,2 个组件通过 @Component @Reusable 声明。状态管理使用 @State(组件私有状态)和 AppStorage(全局共享状态)。页面路由使用 router 模块的 push/getParams/back。
五、核心代码深度剖析
5.1 端侧重建:从照片到 3DGS 模型
SpatialReconService 是整个重建流程的调度中枢。它封装了 SpatialImageGenerator 的完整调用链,并设计了清晰的状态机:
typescript
export class SpatialReconService {
private static instance: SpatialReconService | null = null;
private supported: boolean = false;
private envReady: boolean = false;
private reconstructing: boolean = false;
// ---- 检查设备支持 ----
checkSupport(): boolean {
const status = spatialImage.SpatialImageGenerator.isSupport();
if (status === spatialImage.SpatialImageStatus.STATUS_SUCCESS) {
this.supported = true;
this.envReady = true;
return true;
}
if (status === spatialImage.SpatialImageStatus.STATUS_AIMODEL_NOT_EXIST) {
this.supported = true;
this.envReady = false; // 需要下载模型
return true;
}
this.supported = false;
return false;
}
// ---- 下载 AI 重建模型 ----
async prepareModel(onProgress: (p: number) => void): Promise<boolean> {
if (this.envReady) { onProgress(1.0); return true; }
const bridge = (progress: number) => {
onProgress(progress <= 0 ? 0 : progress >= 100 ? 1 : progress / 100);
};
const status = await spatialImage.SpatialImageGenerator.prepareEnv(bridge);
if (status === spatialImage.SpatialImageStatus.STATUS_SUCCESS) {
this.envReady = true;
return true;
}
return false;
}
// ---- 从单张 2D 图像生成 3DGS 模型 ----
async reconstruct(
pixelMap: image.PixelMap,
modelUri: string,
type: spatialImage.SpatialImageModelType =
spatialImage.SpatialImageModelType.MODELTYPE_GS
): Promise<boolean> {
if (this.reconstructing) return false;
if (!this.envReady) {
const ready = await this.prepareModel(() => {});
if (!ready) return false;
}
this.reconstructing = true;
try {
const status = await spatialImage.SpatialImageGenerator.generate(
pixelMap, type, modelUri);
return status === spatialImage.SpatialImageStatus.STATUS_SUCCESS;
} finally {
this.reconstructing = false;
}
}
}
这里有几个关键设计决策:
checkSupport()设计为同步方法 :因为底层isSupport()本身就是同步静态方法,没必要包一层 Promise。同步返回值可以直接用在条件分支中,调用方代码更简洁。- 防重入设计 :
reconstructing布尔锁防止用户重复点击"开始重建"按钮。3DGS 重建是计算密集型任务,并行发起会导致未定义行为。 - 自动环境准备 :
reconstruct()内部会自动检查并调用prepareModel(),降低调用方的认知负担------调用方不需要关心模型是否已经下载。 - 进度归一化 :底层
prepareEnv返回0~100的整数进度,我在桥接层将其归一化为0~1的浮点进度,与页面层的ReconstructProgress结构对齐。
5.2 3DGS 渲染:加载、变换、滤镜
SpatialRenderService 负责将 .ply 文件变成屏幕上可交互的 3D 场景:
typescript
export class SpatialRenderService {
private renderContext: RenderContext | null = null;
private scene: Scene | null = null;
private rotationMap: Map<Node, number> = new Map();
async init(): Promise<void> {
const rc = Scene.getDefaultRenderContext();
if (rc === null) return;
this.renderContext = rc;
this.renderContext.loadPlugin(spatialRender.GSPlugin.PLUGIN_ID);
this.scene = await Scene.load();
}
async loadModel(uri: string): Promise<spatialRender.GSNode> {
const settings: spatialRender.GSImportSettings = { uri, offset: 0 };
const gsNode = await spatialRender.GSPlugin.loadGSNode(
this.scene, settings, this.scene.root);
gsNode.visible = true;
return gsNode;
}
// 围绕 Y 轴旋转(四元数,避免万向锁)
rotateView(gsNode: spatialRender.GSNode, deltaAngle: number): void {
const current = this.rotationMap.get(gsNode as Node) ?? 0;
const next = current + deltaAngle;
this.rotationMap.set(gsNode as Node, next);
const half = next / 2;
gsNode.rotation = {
x: 0, y: Math.sin(half), z: 0, w: Math.cos(half)
};
}
async applyRetroEffect(camera: Camera): Promise<void> {
const rf = this.scene.getResourceFactory();
const effect = await rf.createEffect({
effectId: spatialRender.GSPlugin.RETRO_EFFECT_ID
}) as spatialRender.RetroEffect;
effect.colorNum = 4; // 减少颜色数量,增强复古感
effect.pixelSize = 4; // 适度下采样
effect.blendEnabled = true;
effect.curve = 0.25;
camera.effects.append(effect);
}
}
关于四元数旋转 :我用 Map<Node, number> 为每个节点维护一个累计旋转角度,每次调用 rotateView 时增量更新并重新计算完整的四元数。这比直接累加欧拉角更安全,因为四元数不存在万向锁(Gimbal Lock)问题。旋转公式是标准的 Y 轴旋转四元数:q = (0, sin(θ/2), 0, cos(θ/2))。
关于复古滤镜 :RetroEffect 通过减少颜色数量(colorNum)和增大像素采样尺寸(pixelSize)来模拟老照片的色带和颗粒感。curve=0.25 控制亮度曲线,让阴影更沉、高光更柔,与文化遗产的"古韵"主题完美契合。
5.3 模型编辑:文物风貌修复
SpatialEditService 让修复工作直接在端侧完成,无需上传到云端工作站:
typescript
export class SpatialEditService {
private editor: spatialEdit.GSEdit | null = null;
startEdit(gsNode: spatialRender.GSNode): spatialEdit.GSEdit {
const editor = spatialEdit.GSEdit.editGSNode(gsNode);
if (editor === undefined) {
throw new Error('无法创建编辑句柄');
}
this.editor = editor;
return editor;
}
paintSelection(r: number, g: number, b: number, a: number, mode: string): void {
const color: Color = {
r: r / 255, g: g / 255, b: b / 255, a: a / 255 // 归一化
};
const paintMode = mode.toUpperCase() === 'REPLACE'
? spatialEdit.PaintMode.REPLACE
: mode.toUpperCase() === 'ADD'
? spatialEdit.PaintMode.ADD
: spatialEdit.PaintMode.MULTIPLY;
this.editor.paint(color, paintMode);
}
async batchRestoreColors(
gsNode: spatialRender.GSNode,
regions: Rect[],
r: number = 184, g: number = 134, b: number = 70, // 青铜古韵色
a: number = 200,
mode: string = 'MULTIPLY'
): Promise<void> {
this.startEdit(gsNode);
for (let i = 0; i < regions.length; i++) {
this.editor!.clearSelection();
this.editor!.selectBy2DBox(regions[i]);
this.editor!.paint(
{ r: r/255, g: g/255, b: b/255, a: a/255 } as Color,
this.parsePaintMode(mode)
);
}
this.editor!.clearSelection();
}
}
颜色归一化踩坑 :ArkGraphics3D 的 Color 结构要求分量范围为 0~1,但 UI 层的颜色选择器通常以 0~255 表示。我在 paintSelection 中做了自动归一化,避免调用方出错。
批量修复设计 :batchRestoreColors 模拟了 AI 辅助的文物风貌还原流程------用户标记多个褪色区域,系统以统一的"青铜古韵色"(RGB 184, 134, 70)批量补色。MULTIPLY 模式将新颜色与原颜色相乘,比直接替换更自然地保留原有纹理层次。
5.4 AR 漫游:让游子"走"进那扇大门
RoamPage 是整个应用的情感核心。它的核心交互是:转动手机,环顾四周------就像你真的站在古建筑前一样。
typescript
@Entry @Component
struct RoamPage {
@State heritage: HeritageItem | null = null;
@State mode: 'roam' | 'info' = 'roam';
private gsNode: spatialRender.GSNode | null = null;
async aboutToAppear(): Promise<void> {
// 1. 加载遗产数据
const items = await FileStorageService.getInstance().loadMetaList();
this.heritage = items.find(it => it.id === this.heritageId);
}
private async onRenderLoad(): Promise<void> {
const renderService = SpatialRenderService.getInstance();
await renderService.init();
// 加载 3DGS 模型
this.gsNode = await renderService.loadModel(this.heritage!.modelUri);
// 创建漫游相机并应用古韵滤镜
const camera = await renderService.createCamera('roamCamera');
await renderService.applyRetroEffect(camera);
this.modelLoaded = true;
}
// 启动陀螺仪,驱动"环顾四周"
private startGyroscope(): void {
SensorService.getInstance().startGyroscope((data) => {
if (!this.gsNode || this.mode !== 'roam') return;
// z 轴角速度对应水平偏航转动
if (Math.abs(data.z) > 0.01) {
SpatialRenderService.getInstance().rotateView(this.gsNode, data.z * 0.1);
}
});
}
// 分享给家人 ------ 分布式同步
private async onShareToFamily(): Promise<void> {
await DistributedService.getInstance().syncHeritageItem(this.heritage!);
promptAction.showToast({
message: '已分享给家人,他们也可以漫游这处古建筑了',
duration: 3000
});
}
build() {
Stack() {
XComponent({ type: XComponentType.SURFACE, controller: this.xComponentController })
.onLoad(() => this.onRenderLoad())
.width('100%').height('100%')
// 顶部信息卡:名称、朝代、简介
this.TopInfoCard()
// 右上角:分享给家人 / 重置视角
Text('分享给家人').onClick(() => this.onShareToFamily())
// 底部:漫游模式 / 信息模式 切换
this.BottomModeSwitch()
// 诗意提示
Text('转动手机,环顾四周------让在外漂泊的游子,重新走进那扇熟悉的大门')
.fontSize(12).fontColor('rgba(255,255,255,0.6)').fontStyle(FontStyle.Italic)
}
}
}
页面底部那句诗不是装饰,而是整个产品的灵魂:
转动手机,环顾四周------让在外漂泊的游子,重新走进那扇熟悉的大门。
陀螺仪驱动视角旋转的系数 0.1 是经过多次调优的:太小则转动迟钝,太大则眩晕。Math.abs(data.z) > 0.01 的阈值过滤了微小抖动,避免模型在静止时微颤。
"分享给家人"按钮背后调用的是 DistributedService.syncHeritageItem(),通过 HarmonyOS 分布式 KV 存储将遗产元数据同步到同一华为账号下的其他设备。这意味着:儿子在深圳用手机重建了老家的祠堂,远方的父亲在北京打开同一个 App,就能"走"进那座祠堂------空间计算让乡愁有了坐标。
六、完整技术链路:从采集到传承
把上面所有模块串联起来,就是 HeritageGuardian 的完整数据流:
用户打开 App
│
▼
首页 Index ── 展示已有遗产档案(FileStorageService.loadMetaList)
│
├── 已有遗产 ── 点击卡片 ──> RoamPage 漫游
│
└── 开始采集 ──> CapturePage
│
▼
相机预览(CameraService.openCamera + XComponent)
│ 用户拍摄 6~12 张多角度照片
▼
照片保存(FileStorageService.saveImage)
│
▼
ReconstructPage ── 启动 3DGS 端侧重建
│
├── SpatialReconService.checkSupport() ← 设备检测
├── SpatialReconService.prepareModel() ← AI模型下载
└── SpatialReconService.reconstructFromImages() ← 生成3DGS
│
▼
进度展示(ScanProgress 组件,5个阶段环形进度)
│
▼
重建完成 ── 保存元数据(FileStorageService.saveMeta)
│
├── 预览 3DGS 模型(XComponent + SpatialRenderService)
│ 支持手指拖动旋转(PanGesture.onActionUpdate)
│
└── 前往 AR 漫游 ──> RoamPage
│
▼
XComponent 全屏渲染 3DGS 场景
│
├── 漫游模式:陀螺仪驱动环顾四周(SensorService + rotateView)
│ └─ 复古滤镜营造历史氛围(applyRetroEffect)
│
├── 信息模式:AR 平面检测 + 历史锚点浮层(AREngineService)
│
└── 分享给家人:分布式同步(DistributedService.syncHeritageItem)
└─ 其他设备接收后可直接漫游同一模型
│
▼
ArchivePage ── 档案管理
│
├── 长按编辑 ──> EditPage
│ └─ GSEdit 选择区域 → paint/remove/undo → saveToPLY
│ └─ 批量风貌修复(batchRestoreColors)
│
├── 删除(FileStorageService.deleteItem)
└── 导出 PLY(SpatialEditService.saveAsPLY)
七、3DGS 移动端优化前沿
在开发过程中,我也跟踪了 2025-2026 年 3DGS 在移动端的前沿研究,这些优化方向将直接影响 HarmonyOS 未来版本的重建与渲染体验:
| 方案 | 会议/时间 | 核心创新 | 性能数据 |
|---|---|---|---|
| Mobile-GS | ICLR 2026 | 深度感知无序渲染 + 一阶SH蒸馏 + 神经向量量化 | 4.8MB / 1098 FPS |
| SEEELE | CVPR 2026 | 混合预处理 + 贡献感知光栅化 | 移动端实时 |
| Mobile3DGS³ | 2026 | 梯度感知超采样 + 帧间插值 | TSGC + 硬件光栅化 |
| Flux-GS | 2026 | Monte Carlo 高光能量聚合 | 移动端实时 |
这些优化方向的核心思路是:降低深度排序开销、压缩球谐系数、剪除冗余高斯、利用帧间连续性 。HarmonyOS 的 spatialImage.generate() 和 spatialRender 底层很可能已经集成了类似的优化,应用开发者只需要调用上层 API 即可受益。
八、踩坑记录与开发心得
8.1 prepareEnv 回调范围
SpatialImageGenerator.prepareEnv() 的回调参数是 0~100 的整数,但应用层的进度通常用 0~1 浮点。我在桥接层做了归一化,同时在 ReconstructPage 中将不同阶段的进度映射到整体进度条的不同区间(下载占 10%~30%,重建占 30%~95%,完成 95%~100%),让用户体验更平滑。
8.2 XComponent 的 Surface 生命周期
XComponent 的 onLoad 回调中不能直接调用异步的相机初始化或渲染初始化,因为 onLoad 是同步回调。正确的做法是将异步逻辑封装为 async 方法,在 onLoad 中触发但不等待:
typescript
XComponent({ type: XComponentType.SURFACE, controller: this.controller })
.onLoad(() => {
this.onRenderLoad(); // async 方法,不 await
})
8.3 颜色分量范围
ArkGraphics3D.Color 的分量范围是 0~1,但 UI 层的颜色选择器通常用 0~255。我在 SpatialEditService.paintSelection() 中做了自动归一化,同时在 UI 层显示 0~255 的整数,符合用户直觉。
8.4 陀螺仪采样频率
默认陀螺仪采样间隔是 20ms(50Hz),对于"环顾四周"这种慢速交互足够了。但如果要支持快速甩头切换视角,可以考虑提高到 10ms(100Hz)。不过采样频率越高,电量消耗越大,需要在体验与功耗之间权衡。
8.5 分布式数据同步的延迟
DistributedService 基于 HarmonyOS 分布式 KV 存储,数据同步延迟在局域网环境下通常在 1 秒以内,但在跨 WAN 场景下可能达到数秒。"分享给家人"的 Toast 提示文案需要考虑这个延迟,避免用户误以为分享失败。
九、结语
写这篇博客的时候,我一直在想一个问题:3DGS 端侧重建的意义到底是什么?
它当然是一项很厉害的技术------把手机变成了一台三维扫描仪,把端侧算力变成了 AI 工作站。但对我而言,它的意义远不止于此。
如果这套系统能真正落地,我最想做的第一件事是:回到家乡的老街,为那座已经有三百年历史的宗祠建立一套完整的数字档案。我想记录下飞檐翘角的每一处纹理,想为斑驳的砖墙保留一份数字副本,更想让在外漂泊的游子,可以通过手机重新"走"进那扇熟悉的大门。
3DGS 端侧重建的意义,对我来说不只是技术的进步,更是让记忆有了形状、让乡愁有了坐标。
HarmonyOS 7 的 Spatial Recon Kit 为开发者打开了一扇大门。从 spatialImage 的端侧重建,到 spatialRender 的实时渲染,再到 spatialEdit 的直接编辑,这套 API 的设计简洁而强大。配合 ArkTS 声明式 UI 和分布式能力,我们完全可以在手机端构建出专业级的文化遗产数字化工具。
希望这篇博客能为同样对空间计算感兴趣的开发者提供一些参考。如果你也在用 3DGS 做有意思的事情,欢迎在评论区交流。
推荐大家体验用AI编程,人工智能学习小站如下,已整理好相应高质量资源:
前言 -- 人工智能学习网
推荐大家体验用AI编程,人工智能学习小站如下,已整理好相应高质量资源:
前言 -- 人工智能学习网
推荐大家体验用AI编程,人工智能学习小站如下,已整理好相应高质量资源:
前言 -- 人工智能学习网