【共创稿事节】HarmonyOS ArkGraphics 3D 实操——让智能音箱的灯环呼吸起来
同一台音箱,薄荷青带来安静的待机感,紫色用短促脉冲提示变化,暖橙则慢慢亮起、缓缓暗下。把灯环交给时间控制,一件静态产品就多了表达状态的方式。
本文案例是独立的 Orbit Light Studio:打开页面时音箱从下方进入展示区,灯环随后亮起;下方可以切换灯效、拖动进度、暂停播放和重播入场。灯环亮度与进度显示读取同一份时间数据。
本文截图与动图均采集自 Mate 60 Pro,模型资源随应用打包,无需运行时下载。
先看入场。产品的高度、缩放和镜头距离同时变化,灯环在模型稳定后进入呼吸节奏。


先绕它看一圈。正面的状态灯逐渐移向侧面,细密网罩绕过背部,最后又回到视线中央。这是同一个 GLB 模型在真机里的连续画面,环绕段以约 4 倍速展示。

一、把灯环从模型中找出来
案例使用一份随应用打包的 GLB 模型。它有环绕机身的网罩孔、深色内衬和圆角金属底座。资源中的 TopRing 是独立几何节点,可以单独覆盖材质。加载失败或节点缺失会显示错误,控制区在加载成功前不可操作。
const material = await factory.createMaterial(
{ name: 'AnimatedRing' }, MaterialType.METALLIC_ROUGHNESS
) as MetallicRoughnessMaterial;
material.material.factor = { x: 1, y: 0.28, z: 0.15, w: 0.5 };
(node as Geometry).mesh.materialOverride = material;
材质在初始化时创建,播放期间修改同一份材质的颜色和自发光因子,避免每一帧重新分配材质。
二、用一个周期描述三种节奏
三种场景都使用 4 秒时间轴。待机做小幅起伏,脉冲把波峰压得更窄,呼吸则用余弦曲线缓慢往返。
const phase = (t % 4) / 4;
// 紫色脉冲:每周期两次短促波峰。
const pulse = 0.12 + 0.88 *
Math.pow((1 + Math.cos(phase * Math.PI * 4)) / 2, 5);
// 暖橙呼吸:从暗到亮,再回到暗。
const breath = 0.12 + 0.88 *
(1 - Math.cos(phase * Math.PI * 2)) / 2;
逻辑时钟每 40ms 更新一次,使用实际经过时间推进进度。这个调度间隔不代表真机渲染帧率,长时间停顿后的单次增量限制在 0.1 秒,避免突跳。
三、把强度写入真实材质
const power = 0.08 + this.level * 1.3;
this.ring.emissive.factor = {
x: this.red * power,
y: this.green * power,
z: this.blue * power,
w: 1
};
场景切换时保存当前颜色和强度,以 500ms 平滑插值过渡到新模式在当前时间的颜色与强度。连续点击不同模式,也从屏幕当前状态开始过渡。暂停时选择模式立即显示对应效果,保持时间位置不动。
自发光因子改变灯环自身的颜色与明亮程度,不会自动照亮周围物体。案例使用自发光材质呈现灯效,不包含 Bloom 泛光或地面反射。
四、三种灯效要看出什么区别
薄荷待机只保留小幅波动,适合表示设备在线;紫色脉冲会出现短促高峰,时间曲线更尖;暖橙呼吸从暗到亮再缓慢回落,节奏最长也最柔和。三种状态使用同一个灯环节点,但颜色、强度曲线和紫色脉冲的轻微环体缩放同时变化。

五、播放、暂停与进度拖动
暂停后保留当前时间和材质状态。拖动进度条时临时暂停,时间直接映射到灯光强度;松手后恢复拖动前的播放状态。下方柱形曲线使用与灯环相同的强度函数,标出周期形状及当前进度。
自动环绕有独立开关,使用相机绕产品移动。手指拖动时关闭自动环绕,相机随手势实时更新;俯仰范围为 -65°~65°,可以观察顶面和底座背面。复位按钮恢复初始角度和时间。
把视线抬到上方,灯环从一条亮边展开成完整圆环,顶盖与机身的连接也更清楚。

反向拖动则进入仰视,观察双层底座的厚度与背面。到达角度边界后,相机停止继续翻转。

想停在某个侧面细看,可以直接左右拖动。手势接管后自动环绕停止,观察方向随拖动改变。

下面这段把暂停、恢复、时间线拖动、自动环绕和手动观察放到同一条操作链里。暂停时连续两帧保持同一灯光状态,恢复后继续变化。

六、退出时收好场景
页面退出会停止定时器,销毁自建材质与场景。加载过程中使用代次标记:若用户在 GLB 加载期间返回,异步结果完成后直接释放,不重新启动播放。
相关事件记录为 LIGHT_READY、LIGHT_MODE、LIGHT_PLAY、LIGHT_VIEW、LIGHT_RESET 和 LIGHT_RELEASE,用于核对交互与退出行为。
七、让旋转后的背景保持干净
连续转动相机时,透明 Surface 曾留下旧轮廓。案例为相机设置不透明清屏色,并让展台背景使用同一颜色:
// 转换为线性颜色,对应界面的 sRGB #090D16。
camera.clearColor = { r: 0.00273, g: 0.004025, b: 0.008023, a: 1 };
模型的金属质感由 PBR 材质的基础色、金属度和粗糙度控制,网罩孔与底座圆角则由几何结构呈现。
文中的四组视角 GIF 来自真机连续采帧,未插值生成中间模型画面;GIF 采样频率不代表应用渲染帧率。
更多推荐

所有评论(0)