首先,苹果对开发者开放的API十分的简单,只需要一行代码就能让你的按钮拥有Liquid Glass效果。但是开发者无法对其做更多的调整。


接下来我们使用第三方的视图Debug工具去寻找Liquid Glass的实现。
 


通过开关几个Layer的isHidden属性我们可以发现,其效果是通过三层CALayer实现,一层负责高光轮廓,一层负责阴影,最后一层负责渲染玻璃内部的形变和模糊。
渲染玻璃内部的形变和模糊的私有类叫做CABackDropLayer,这里我们可以使用 OC Runtime Browser 工具,在iOS 26的模拟器下运行,提取出这个私有类的头文件。

https://github.com/nst/RuntimeBrowser

iOS 26 CALayer头文件


通过和 iOS 18 的头文件diff可知,新系统多了几个关键参数,我们可以通过lldb来调用和调整这几个参数,以下是参数和它的含义。

  • tracksLuma //是否跟踪玻璃下方的背景来调整玻璃颜色的深浅
  • lumaSubrect //跟踪背景色的区域
  • allowsFilteredLuma //是否允许给玻璃添加黑色或白色图层
  • lumaUpdateRate// 跟踪背景亮度的速度

比如这里的玻璃效果,通过设置只跟踪左上角的一个像素,可以生成这样背景大部分都是白色,但是玻璃自动变成了黑色效果。

(lldb) expr (void) [(CABackdropLayer *) 0x60000172dcc setLumaSubrect: (CGRect){0,0,1,1}]

 

在iOS26之前,苹果大量使用的高斯模糊风格,同样是通过CABackdropLayer实现的,他的原理是通过私有的高斯模糊CAFilter 采样下方像素并作替换。这里我们猜测他的原理近似,于是我们可以通过lldb打印出filter。

(lldb) po [(CABackdropLayer *) 0x6000017655c0 filters]
<__NSSingleObjectArrayI 0x600000028fc0>(
glassBackground
)



我们看到果然是这是iOS 26新增的CAFilter类型 glassBackground。
同样的,我们可以参照头文件设置其相关参数。

CAFilter 头文件

https://github.com/ktiays/GlassExplorer
更详细的Keypath 参数设置,可以参考上方的开源项目

 

那么我们想要探究filter下的原始图像究竟是什么,就需要禁用掉glassbackground Filter,这里我们直接使用一个简单粗暴的method swizzle去block掉所有的setFilters方法。

Method Swizzle具体实现

于是我们就可以看到下方SDFLayer长什么样子了。
 

 

所有的Glass效果都变成了这样的蓝绿相间的纹理。
这就到了下一层SDFLayer了,SDF的全称叫做,Signed Distance Fields 是一种图形轮廓的描述方式。他不直接描述物体表面的坐标,而是存储空间每个点到图形的最近距离。能够实现动态的和连续的物体融合效果。这就是苹果Glass之间实时动态融合的原理。

融合动画
两个使用SDF描述的物体,可以轻松实现参数可调的平滑融合

而这些纹理似乎是每一点的SDF梯度贴图,但由于映射原因无法展示完全。

同时SDFLayer又有SDFEffect类作为其配置。
可以看到头文件中有大量的SDFEffect子类,提供了特别丰富的物理参数可供调节。

比如在选择锁屏这个典型场景下,仅需要在SDFEffect中,将高光的采样范围调整到非常大的数值,就能获得特别棒的效果。

简单总结一下Liquid Glass的原理如下图所示。

 


而在性能上,我这里做了一个极端场景下的实验,将整个屏幕铺满Liquid Glass,并滑动屏幕让其不断渲染,同时使用Instruments获取CPU主线程(UI绘制线程)的资源占用情况。

可以看到,Liquid Glass的平均资源消耗,是过去Material高斯模糊的两倍。这对iPhone的性能和续航又提出了更强的要求。

好了,以上就是我对Liquid Glass的简单的定性探索,欢迎大家批评指正。

关于我

我是一名客户端程序员,一位前不知名数码博主,一位iOS独立开发者。全网同名,欢迎关注,带你探索不一样的数码世界。