A Swift package that renders real-time liquid glass effects using Metal shaders. Drop it onto any SwiftUI view to get frosted glass with refraction, chromatic dispersion, rim lighting, and cursor/gaze-reactive highlights.
Runs on macOS 14+, iOS 17+, and visionOS 1+.
Add CrystalKit to your project via Swift Package Manager:
dependencies: [
.package(url: "https://github.com/omnideaco/CrystalKit.git", from: "0.1.1")
]Or in Xcode: File > Add Package Dependencies, paste the repo URL, and pick the version.
import SwiftUI
import CrystalKit
struct ContentView: View {
var body: some View {
Text("Hello, Glass")
.padding()
.crystalGlass()
}
}That's it. The modifier captures the backdrop behind the view, blurs it, and composites a glass material with refraction, rim lighting, and edge effects.
CrystalKit ships with four presets:
.crystalGlass(.regular) // Default everyday glass
.crystalGlass(.clear) // Transparent, subtle refraction
.crystalGlass(.subtle) // Barely-there frosting
.crystalGlass(.frosted) // Heavy blur, strong refractionOr build your own:
.crystalGlass(CrystalGlassStyle(
frost: 0.7, // 0 = clear, 1 = fully frosted
refraction: 0.4, // Edge warping strength
dispersion: 0.2, // Chromatic color separation
lightIntensity: 0.8 // Rim light brightness
))| Property | Range | Default | Description |
|---|---|---|---|
frost |
0–1 | 0.5 | Background blur intensity. 0 = clear, 1 = fully frosted. |
refraction |
0–1 | 0.35 | How much background content bends at the glass edges. |
dispersion |
0–1 | 0.15 | Chromatic color separation (rainbow fringing) at edges. |
depth |
0–1 | 0.0 | Magnification zoom through the glass lens. |
splay |
0–1 | 0.25 | Radial barrel distortion of the background. |
lightIntensity |
0–1 | 0.6 | Rim light brightness and edge extent. |
lightBanding |
0–1 | 0.5 | Rim light gradient falloff. 0 = sharp cutoff, 1 = soft fade. |
lightRotation |
0–1 | 0.6 | Light source angle. 0 = top, 0.25 = right, 0.5 = bottom, 0.75 = left. |
edgeWidth |
0–1 | 0.05 | How far refraction extends inward from shape edges. |
resonance |
Bool | false | Adaptive tinting — dark backgrounds tint lighter, light backgrounds tint darker. |
tintColor |
Color? | nil | Optional color overlay on the glass surface. |
tintOpacity |
0–1 | 0.0 | Tint blend amount. Only applies when tintColor is set. |
variant |
.regular / .clear | .regular | Glass material variant. Clear reduces light intensity to 70%. |
cornerRadius |
CGFloat? | nil | Override corner radius. nil = inferred from clipping shape. |
lightSource |
.fixed / .cursor(...) | .fixed | Light tracking mode. See Cursor-Reactive Lighting. |
Glass clips to standard SwiftUI shapes, built-in descriptors, or any custom path via SDF textures:
// SwiftUI shapes
.crystalGlass(.regular, in: Capsule())
.crystalGlass(.regular, in: Circle())
.crystalGlass(.regular, in: RoundedRectangle(cornerRadius: 16))
// Polygons and stars
.crystalGlass(.regular, shape: .polygon(sides: 6, cornerRadius: 4))
.crystalGlass(.regular, shape: .star(points: 5, innerRadius: 0.4))
// Custom paths — provide a pre-computed SDF texture for any arbitrary shape
.crystalGlass(.regular, shape: .custom(sdfTexture: mySdfTexture, padding: 8))The .custom case accepts a Metal SDF (signed distance field) texture, so you can render glass on any shape you can rasterize — bezier paths, boolean operations, hand-drawn outlines, anything.
On macOS, glass can track the mouse. On iOS, it tracks where the user is looking via ARKit face tracking.
// Follows cursor/pointer automatically
var cursorStyle: CrystalGlassStyle {
var style = CrystalGlassStyle.regular
style.lightSource = .cursor()
return style
}
Text("Hover me")
.crystalGlass(cursorStyle)The .cursor() case accepts two optional parameters:
| Parameter | Default | Description |
|---|---|---|
falloffRadius |
300 | Distance in points where light fades to baseIntensity. nil = angle-only (no distance falloff). |
baseIntensity |
0.3 | Minimum light intensity when cursor/gaze is far away (0–1). |
// Wider reach, brighter at rest
style.lightSource = .cursor(falloffRadius: 600, baseIntensity: 0.5)
// Angle-only — light direction follows cursor, intensity stays constant
style.lightSource = .cursor(falloffRadius: nil)On iPhone/iPad with TrueDepth or Neural Engine, CrystalGazeTracker projects the user's gaze direction to screen coordinates via ARKit face tracking.
@StateObject private var gaze = CrystalGazeTracker()
var body: some View {
MyContent()
.crystalGazePoint(gaze.gazeScreenPoint)
.onAppear { gaze.startCalibration() }
}The guided calibration shows three target dots the user looks at, then computes accurate per-axis scale factors. Observe gaze.calibration to build a calibration overlay UI:
switch gaze.calibration {
case .idle: // Not calibrating
case .lookingAt(let point, let step, let totalSteps, let progress):
// Show target dot at `point`, progress bar at `progress`
case .complete: // Ready to use
}You can tune the tracker after calibration:
| Property | Default | Description |
|---|---|---|
smoothing |
0.4 | Gaze interpolation (0 = raw, 1 = heavy smoothing). |
horizontalScale |
8.0 | Horizontal projection multiplier. Set by calibration. |
verticalScale |
8.0 | Vertical projection multiplier. Set by calibration. |
samplesPerTarget |
40 | Frames collected per calibration target point. |
Requires NSCameraUsageDescription in Info.plist.
CrystalKit samples the backdrop luminance and automatically sets the child view's foreground style to white (dark backgrounds) or black (light backgrounds). Read the value yourself via the environment:
@Environment(\.crystalGlassLuminance) var luminanceBy default, CrystalKit captures the screen behind the view using CGWindowListCreateImage (macOS) or UIView snapshotting (iOS). If you're already rendering with Metal (like a canvas app), you can supply the backdrop texture directly to avoid screen capture permissions and flicker:
class MyProvider: CrystalBackdropProvider {
func backdropTexture(for rect: CGRect, scale: CGFloat) -> MTLTexture? {
// Return your Metal texture cropped to rect
}
}
MyView()
.crystalBackdrop(myProvider)| Platform | Minimum |
|---|---|
| macOS | 14.0 |
| iOS | 17.0 |
| visionOS | 1.0 |
| Swift | 6.2 |
Requires a Metal-capable GPU (all supported platforms have one).
MIT. See LICENSE for details.
