ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【共创稿事节】HarmonyOS 7是3DGS 端侧重建:空间建模类应用的设计机会

【共创稿事节】HarmonyOS 7是3DGS 端侧重建:空间建模类应用的设计机会 做 3D 内容最劝退的一环从来不是渲染是把真实世界搬进屏幕。建模师在 DCC 里拉几天面片导出几十兆模型到手机上还要重新减面、重烘焙贴图。3DGS3D Gaussian Splatting绕开了这条路径拍一段视频用一组带属性的高斯点去逼近真实场景光影和纹理几乎是采集来的。HarmonyOS 7API 26把这件事放到了端侧Spatial Recon Kit 提供加载与渲染能力设计侧要回答的问题随之变了——不再是怎么把模型做小而是拿到真实空间之后应用还能做什么。3DGS 和传统建模描述的是两种东西传统建模在描述表面。顶点、三角面、UV、贴图组成一层壳光照由材质和灯光实时计算模型是空心的形状。3DGS 描述的是体积几十万到几百万个高斯点Gaussian Point填充空间每个点带位置、颜色、透明度、旋转和缩放渲染时投影到屏幕按深度做 alpha 混合叠加出完整的场景。这个差别会传导到工作流上。传统流程的成本大头在建模和贴图3DGS 的成本大头在采集和算力。前者考验美术水平后者考验数据质量。维度传统多边形建模3DGS 重建数据来源人工建模 贴图绘制拍摄采集 算法重建典型体量单模型数 MB 到数十 MB单场景数十 MB 到数百 MB结构有拓扑可编辑、可动画点云式无拓扑编辑受限真实感依赖美术能力依赖采集质量光影天然保留视角表现视差正常视差正常非全景单点环视文件格式glTF / GLB / FBXMP4 / PLY / GLB渲染开销受面数、材质影响受同屏高斯点数量影响fillrate 敏感看清这张表后面的设计取舍就有依据了3DGS 换来了真实感代价是体积和渲染压力都更大。端侧重建改掉的三个前提真实资产不用再造家具应用要给用户看一张真实沙发过去只能买模型、或者扫描后云端重建再下载。端侧重建把采集、重建、渲染放进同一台设备用户拍到的就是拿到的。对设计来说这意味着内容供给不再是瓶颈——产品可以先做互动再补资产。迭代周期从天压到小时内容团队改一个展厅布局2D 时代要重新出图、切图、发版。3DGS 场景可以整段替换重建一次就能看效果。评审从看图变成进场景走一遍反馈更直接返工更少。数据不出设备卧室、店铺内部、工厂车间这类空间拍完上传到云端本身就涉及隐私与合规。端侧完成重建原始采集数据可以只留在本地重建结果也由用户决定是否分享。这不只是技术选项是很多场景能不能做的前提。把模型加载进场景Spatial Recon Kit 的入口是spatialRender它依赖kit.ArkGraphics3D的 Scene 与渲染上下文。顺序不能乱先注册插件 ID再加载场景最后挂 GS 节点。// entry/src/main/ets/entryability/EntryAbility.etsimport{Scene,RenderContext,Node}fromkit.ArkGraphics3D;import{spatialRender}fromkit.SpatialReconKit;EntryComponentstruct GsViewer{privatescene:Scene|nullnull;aboutToAppear():void{// 1. 拿到默认渲染上下文后续插件注册都挂在它上面constrenderContext:RenderContext|nullScene.getDefaultRenderContext();if(renderContextnull){console.error(no render context, abort);return;}// 2. 必须先注册 GSPlugin否则调用 GSPlugin 的接口属于未定义行为renderContext.loadPlugin(spatialRender.GSPlugin.PLUGIN_ID);// 3. 加载场景成功后把 3DGS 节点挂到根节点下Scene.load().then(async(scene:Scene){this.scenescene;if(!scene.root){return;}constroot:Nodescene.rootasNode;// uri 支持 OhosRawFile:// 与 file:// 两种前缀格式支持 mp4 / ply / glbconsturiOhosRawFile://assets/gltf/room.glb;constgsNode:spatialRender.GSNodeawaitspatialRender.GSPlugin.loadGSNode(scene,{uri,offset:0},root);// GSNode 继承自 Node可直接做位移、缩放、可见性控制gsNode.position{x:0,y:-0.2,z:0};gsNode.scale{x:1,y:1,z:1};gsNode.visibletrue;}).catch((err:string){console.error(load 3dgs failed: err);});}build(){Column(){if(this.scene){// Component3D 负责把 Scene 渲染出来尺寸交给布局Component3D({scene:this.scene}).width(100%).height(100%)}}.width(100%).height(100%)}}一个房间用loadGSNode就够了。但一栋楼、一个园区不行——几百 MB 的高斯点不可能一次性进内存。API 26 引入的分块 3DGSTiled 3D Gaussian Splatting解决的就是这个把场景按空间切成瓦片渲染器在相机移动时按需请求当前视口附近的瓦片。// 大场景按需加载相机移到哪渲染器就请求哪一片constparams:spatialRender.TiledGSImportSettings{uri:file:///data/storage/el2/base/files/campus/campus.scene.json// 清单文件描述瓦片层级};consttiled:spatialRender.TiledGSNodeawaitspatialRender.GSPlugin.loadTiledGSNode(scene,params,root);// 指定驱动分块选择的相机相机的位置决定了要加载哪些瓦片tiled.setCamera(camera);// 渲染器需要数据时回调应用负责把瓦片拉到本地再通知就绪tiled.setTileRequestCallback((tiles:spatialRender.GSTile[]){for(consttileoftiles){// 远端拉取 - 落盘到 tile.uri 指向的相对路径 - 通知渲染器可读voiddownloadTile(tile.uri).then((){tiled.notifyTileReady(tile);});}});分块加载把一次性几百 MB变成首屏几 MB 走到哪加载到哪。设计上要多考虑一件事瓦片加载是有延迟的远景区域会先以低精度出现再逐步清晰。这不是 bug是设计要接受的渐进呈现。设计机会不止看模型刚上手容易把 3DGS 当成更真实的模型预览。真正有意思的是它上面叠的那一层交互。场景标注层高斯点是死的、不可拾取的手势和视线需要一个可命中的目标。做法是在场景里挂普通 Node 作为热点用 Raycast 拾取这些 Node而不是去点高斯点本身。虚拟陈设真实房间重建后叠加 glTF 家具用位移和缩放调整位置做摆放前先看效果。空间导览Tiled 场景配合相机路径做展馆、厂区的走动式浏览。隐私敏感建模卧室、试衣间、店铺内部端侧完成原始数据不外传。记录与回访装修前拍一遍留底之后随时进入对比。约束在哪里设计就得在哪里让步约束具体表现设计对策模型体量单场景可达数百 MB大场景走 Tiled 分块小场景控制采集范围渲染性能同屏高斯点过多会掉帧限制相机拉近距离默认视距保持中景加载延迟瓦片按需拉取远景先模糊接受渐进呈现用进度提示代替转圈等待交互命中高斯点不可直接拾取叠加可拾取 Node 作为交互代理设备支持暂不支持模拟器仅境内设备降级方案要准备开发期用真机验证数据格式MP4 / PLY / GLB 三种按用途选PLY 保真、MP4 体积小、GLB 便于混合管线案例家具摆放应用设想一个先看再买的家居应用用户拍一段客厅视频端侧重建成 3DGS 场景再从商品库选沙发、茶几拖进去看比例、看风格满意了直接下单。流程拆开看是这样引导用户环绕拍摄端侧重建 3DGS 场景加载 GSNode 进入场景按地面重建锚点平面拖入 glTF 家具模型Raycast 拾取 位移缩放截图 / 录像分享这个案例里设计上最容易被忽略的是D 这一步。重建出来的场景没有地面这个概念是用户把家具放到半空中、还是贴到地上全靠应用自己建立一个参考平面。常见做法是从点云的低处拟合一个水平面或者让用户点两下地面手动定标。定标准不准直接决定整个摆放体验可不可信。第二个坑是拾取。用户觉得自己在点沙发实际点的是空气——因为高斯点不参与拾取。所以每个家具都要挂一个不可见的包围盒 Node 作为代理视觉上是 3DGS 家具交互上命中的是代理盒。几条小经验总结哦插件注册是硬前提。loadPlugin漏掉或顺序反了后面所有 GSPlugin 调用都可能拿到未定义行为而且不一定报错排查起来很费时间。采集质量直接决定上限。晃动、强反光、纯色墙面都是重建杀手引导页要把慢走、平稳、覆盖多角度讲清楚。GSNode 是普通 Node位移缩放照常用但别指望它像 glTF 那样按子节点拆开编辑。大场景一律先想 Tiled不要等到内存爆了再改架构。模拟器跑不了这个 Kit早点上真机别把时间花在环境上。uri前缀写错。OhosRawFile://读的是 rawfilefile://读的是应用沙箱路径两者不能混用。忘记判断scene.root是否为空后续as Node会直接崩。把 Tiled 场景的相机忘了设置渲染器只能默认用当前场景相机分块选择可能不符合预期。在瓦片回调里同步做网络请求阻塞渲染线程应该异步拉取、落盘后再notifyTileReady。采集数据和重建结果都放沙箱没做清理策略用几次就把用户存储占满。
返回列表