Spark AR开发中如何实现平面仅在拍照捕获时显示
问题根因
你的判断完全正确。Spark AR的拍照捕获执行逻辑存在时序差:系统会先完成当前帧的全量渲染、把帧内容写入捕获缓冲区,之后才会抛出isCapturingPhoto状态变更的信号。你在信号触发后才修改plane.hidden = false,这个改动只会作用在捕获完成后的下一帧预览画面,根本不会被写入最终输出的照片,自然看不到效果。
可落地实现方案
方案1:前置显隐+延时复位(适配所有Spark AR版本,代码量小)
核心逻辑是不要等捕获信号触发才操作平面,而是监听捕获开始的前置回调,提前1帧左右把平面设为可见,等捕获完成后自动切回隐藏,代码如下:
const Scene = require('Scene'); const CameraInfo = require('CameraInfo'); const Time = require('Time'); // 初始化时平面默认隐藏 (async () => { const plane = await Scene.root.findFirst('your_plane_object_name'); plane.hidden = true; CameraInfo.onCaptureBegin.subscribe(() => { // 提前16ms(约单帧渲染时长)显示平面,保证内容被渲染进捕获缓冲区 plane.hidden = false; // 捕获完成后复位隐藏,300ms延时可覆盖绝大多数机型的捕获耗时,不会漏复位 Time.setTimeout(() => { plane.hidden = true; }, 300); }); })();
低端设备如果出现成片里平面没显示的情况,把
plane.hidden = false的逻辑放到Time.setTimeout(..., 0)里提前到事件队列最前面执行即可,不要加额外延时。
方案2:捕获专属渲染层(无预览闪烁,体验最优)
这是官方推荐的无代码方案,完全避免手动切显隐导致的预览画面闪一下平面的问题:
- 打开编辑器的图层管理面板,新建一个独立图层,命名为
capture_only - 把带纹理的平面移动到这个新建图层下
- 选中场景里的相机对象,在右侧属性面板找到「捕获渲染设置」,把
capture_only图层设置为仅捕获阶段可见,预览阶段排除该图层
配置完成后不需要写任何控制代码,实时预览全程看不到平面,只有最终拍出来的照片里会显示平面内容,不会有任何时序问题。
避坑说明
- 不要用
ObjectVisibility类实现这个需求,该类的状态更新绑定预览帧渲染队列,优先级低于捕获帧的渲染流程,会出现状态同步延迟 - 如果平面上挂载的是动态生成的纹理(比如实时文字、动态贴纸),提前显示前要校验纹理的加载状态,避免捕获到空白平面
内容的提问来源于stack exchange,提问作者rickel_pick
相关产品推荐
相关产品推荐

