概要
- AppleのLiquid Glassエフェクト をWebで再現する技術解説
- CSS・SVGディスプレイスメントマップ ・屈折計算を活用した実装方法
- Snellの法則 を基礎に光の屈折挙動をシミュレーション
- 円形ガラス表面 を例に、変位ベクトルフィールドを作成
- SVGフィルター活用手順 とマッピング方法の詳細解説
Apple Liquid GlassエフェクトをWebで再現する
- AppleがWWDC 2025で発表したLiquid Glass は、曲面ガラスのような屈折・ハイライトを持つUIエフェクト
- 本記事では CSS・SVG・物理ベース屈折計算 を使い、Web上で近似再現する手法を解説
- ピクセル単位の完全再現ではなく、コアとなる屈折・ハイライト表現にフォーカスしたプロトタイプ構築
- 光の屈折現象 を物理法則から解説し、段階的に実装手順を紹介
屈折現象の基礎とSnellの法則
- 屈折 とは、光が異なる媒質(例: 空気→ガラス)を通過する際に進行方向が変化する現象
- 光の進行速度が媒質ごとに異なるため、 入射角と屈折角 の関係が生まれる
- Snellの法則: n₁sinθ₁ = n₂sinθ₂
- n₁: 第一媒質の屈折率
- θ₁: 入射角
- n₂: 第二媒質の屈折率
- θ₂: 屈折角
- n₂=n₁なら光は直進、n₂>n₁なら法線方向に曲がり、n₂<n₁なら法線から離れて曲がる
- 入射角が大きい場合は 全反射 が発生する場合もある
本プロジェクトの制約事項
- 媒質は空気(屈折率1.0)とガラス(1.5) のみを想定
- 屈折は1回のみ (複数回の屈折や出射は無視)
- 入射光は背景面に垂直 (パースなし)
- 2D形状(円形のみ) を対象とし、背景面とガラスの間に隙間なし
- これらの制約により、 Snellの法則に基づく計算を簡略化
ガラス表面の定義と表面関数
- ガラス表面は 数式関数で定義 し、ベゼル端から中心までの厚みを表現
- height = f(distanceFromSide) で各点の高さを算出
- 法線ベクトル は微分値を-90度回転して求める
- 例:
- Convex Circle: y = √((1 - (1 - x))²)(球面ドーム)
- Convex Squircle: y = ⁴√((1 - (1 - x))⁴)(Apple風スクイークル、滑らかな曲率遷移)
- Concave: y = 1 - Convex(x)(凹型、外側へ屈折)
- Lipy: ConvexとConcaveをSmootherstepでブレンド(中央が浅いリム形状)
シミュレーションと屈折ベクトル
- 各表面関数ごとに 光線の屈折シミュレーション を実施
- 凹面は光を外側に、凸面は内側に曲げる傾向
- Apple Liquid Glassは主に凸面プロファイル を採用
- 対称性を利用し、ベゼルからの距離ごとに変位量を事前計算 して再利用
変位ベクトルフィールドの作成
- ガラス表面全体の変位ベクトルフィールド を計算
- 円形の場合、変位方向は常に境界に直交
- 半径上を127分割してサンプリング (SVGマップ解像度制約)
ベクトルの正規化と最大変位量
- 最大変位量で正規化 し、全ベクトルの最大値を1.0にスケーリング
- displacementVector_normalized = { angle, magnitude / maximumDisplacement }
- 最大変位量はSVGフィルタのscale値として利用
SVGディスプレイスメントマップの生成
-
SVGの<feDisplacementMap /> で屈折を表現
-
ディスプレイスメントマップは 32bit RGBA画像 で表現
- R: X軸変位、G: Y軸変位、B/Aは無視
- 8bit(0–255)で-128~127ピクセルの範囲を表現
-
scale属性 で実際のピクセルシフト量を調整
<svg colorInterpolationFilters="sRGB"> <filter id={id}> <feImage href={displacementMapDataUrl} x={0} y={0} width={width} height={height} result="displacement_map" /> <feDisplacementMap in="SourceGraphic" in2="displacement_map" scale={maximumDisplacement} xChannelSelector="R" yChannelSelector="G" /> </filter> </svg>
ベクトル→RGBA値の変換
-
極座標(角度・大きさ)→直交座標(X・Y) に変換
-
正規化済みベクトルを0~255の範囲にマッピング
const x = Math.cos(angle) * magnitude; const y = Math.sin(angle) * magnitude; const result = { r: 128 + x * 127, g: 128 + y * 127, b: 128, // Blueは未使用 a: 255, // Alphaは常に不透明 };
Playgroundと最終レンダリング
- Playgroundで表面形状・ベゼル幅・厚み・スケールを調整可能
- 入力値に応じて 屈折フィールド・ディスプレイスメントマップ・最終描画 が変化
- Apple Liquid Glass風UIエフェクトのWeb再現 を体験可能
このように、 物理ベースの屈折計算とSVGフィルタ を組み合わせることで、Apple Liquid Glassのような 没入感あるガラスUIエフェクト をWeb上で実現可能。 CSSやSVGの知識に加え、光学的理解 が重要なポイント。