A deep-dive into deconstructing and replicating SwiftUI’s Liquid Glass effects using lower-level
Core Animation
layers likeCABackdropLayer
,CASDFLayer
, and related private types. This project aims to expose and customize the visual building blocks of these effects, especially on macOS.
The reconstructed effect is built from a multi-tiered CALayer
hierarchy. Each layer has a specific responsibility, with named sublayers and filters orchestrated to simulate SwiftUI's original visual output.
CustomGlassView (NSView)
└── SwiftUI.SDFLayer (CALayer subclass, optional wrapper)
├── CABackdropLayer
│ └── CASDFLayer ("@0")
│ └── CALayer (container)
│ └── CASDFElementLayer
├── CASDFLayer ("@1") – glass highlight
│ └── SDFPortalLayer → sources CASDFElementLayer
└── CASDFLayer ("@2") – glass highlight
└── SDFPortalLayer → sources CASDFElementLayer
SwiftUI.SDFLayer
(optional): Subclass ofCALayer
with hidden delegate logic, possibly auto-inserted by SwiftUI.CABackdropLayer
: Renders the primary distorted background usingglassBackground
filter.CASDFLayer
(@0
): Provides SDF texture for backdrop layer viaCASDFOutputEffect
.CASDFElementLayer
: Defines the SDF shapeCASDFLayer
(@1
,@2
): Add glass edge highlights at opposite angles usingCASDFGlassHighlightEffect
and avibrantColorMatrix
filter.SDFPortalLayer
: A variant ofCAPortalLayer
for SDF pipelines, mirroring theCASDFElementLayer
into highlight layers.
-
glassBackground
(CAFilter):- Receives
inputSourceSublayerName = "@0"
- Applies various refraction, blur, vibrancy, and tone mappings
- Receives
-
CASDFOutputEffect
:- Translates shape layers into backdrop-compatible SDF textures
-
CASDFGlassHighlightEffect
:- Applies direction-based highlights to simulate edge lighting
-
vibrantColorMatrix
(CAFilter):- Applies a custom 4×5 color matrix to tone the highlight layer output
-
Reproduce basic
glassBackground
effect on macOS → Partial: structure functional, filter tuning ongoing -
Reproduce Liquid Lens effect (as can be seen in Slider or Toggle) → In progress
-
Port effect and hierarchy to iOS → Not started, should be easy