終於來到最後一天了~呼呼。
最後一天想回到 UI,研究一個我一直很感興趣的主,iOS 的液態玻璃。
👉🏿 Demo 連結
Apple 在 iOS 26 導入 Liquid Glass(液態玻璃)設計,以帶有流動感與空間感的透明材質重新塑造介面。
按鈕、工具列與導覽元件看起來像真正的玻璃。背景穿過元件時會產生折射,邊緣則會出現反光與些微色彩變化;再加上半透明與霧化,玻璃便能融入不同背景,同時維持文字的辨識度。
它和常見的毛玻璃效果不太一樣。
一般毛玻璃大多是把背景模糊,再疊上一層透明白色和亮色邊框。這種方法可以表現「霧面玻璃」,卻少了玻璃最明顯的特徵:折射。
真正的玻璃會讓光線改變方向。觀察一塊厚玻璃時,可以發現中央區域大致清楚,畫面到了彎曲的邊緣才會明顯變形。這個被壓縮、偏移的邊緣,正是液態玻璃看起來有厚度的原因。
不過 Apple 的效果運行在作業系統裡,瀏覽器沒有完全相同的材質 API,那麼網頁上要怎麼模擬呢?
這次我參考了 Outpace Studios 的文章:Liquid glass for the web。
要做出可信的玻璃,第一步不是調整模糊程度,而是先描述玻璃的形狀。
這次把選單視為一塊帶有圓角的凸面玻璃。玻璃中央接近平面,越靠近邊緣,表面彎曲得越明顯。當光線從背景穿過這塊玻璃時,入射角會隨著曲面斜率改變,因此產生不同程度的位移。
折射方向可以透過司乃耳定律計算。簡單來說,光線進入另一種材質時會改變方向,而折射率決定它彎曲多少。一般玻璃的折射率大約是 1.5,所以這次也使用接近這個數值來建立折射效果。
計算完成後,會得到一張「位移圖」。它不是最後看到的玻璃外觀,而是一張記錄每個位置應該把背景往哪裡移、移動多少的資料圖。
玻璃中央的曲面斜率接近零,所以位移很小;到了圓角和邊緣,曲面快速下降,位移也會變得明顯。這樣產生的結果比直接畫一圈扭曲漸層自然,四個圓角之間也能連續過渡,不會出現折線或突然轉向。
反光也可以從同一個玻璃曲面推算。面向光源的邊緣會比較亮,另一側只保留較淡的反射,讓玻璃看起來有厚度和方向感。
有了位移圖之後,下一步是讓它真正影響背景。
SVG 的 feDisplacementMap 濾鏡可以依照位移圖,重新安排影像中的像素。位移圖的紅色與綠色通道分別控制水平和垂直方向,因此玻璃邊緣可以將後方畫面往內壓縮或向外拉動。
但這裡有一個問題:SVG 濾鏡需要一張可以處理的影像,不能在所有瀏覽器裡直接取得元件後方的即時畫面。
常見做法是搭配 backdrop-filter,直接對元件背後的內容套用濾鏡。不過 SVG 位移效果在不同瀏覽器上的支援並不一致,有些瀏覽器最後只會留下模糊,折射則完全消失。
參考文章採用了另一種方式:複製一份背景。
頁面先保留原本可操作的背景,再把相同內容複製到玻璃元件中。這份副本會對齊原本的位置,因此看起來就像玻璃直接取樣了後方畫面。接著只對副本套用 SVG 位移濾鏡,原本的頁面仍然保持正常,也不會受到玻璃影響。
當背景移動、控制器改變視角或漣漪擴散時,玻璃裡的副本也需要同步更新。這樣折射的就不是一張靜態截圖,而是目前正在變化的畫面。
選單收合時是一塊短矩形,點擊後會維持相同寬度,向下延伸成完整清單。視覺上不是突然出現另一塊面板,而是同一塊玻璃被拉長。
展開動畫也帶來一個問題:如果直接把原本的折射圖跟著高度一起拉伸,圓角和邊緣就會變形,反光也會被拖成長條。
因此折射表面需要拆成不同區域處理。上方與下方的玻璃邊緣保持固定厚度,中間區域才隨著選單高度延伸。如此一來,動畫過程中的圓角不會被壓扁,折射範圍也能跟著玻璃尺寸自然改變。
背景中的漣漪同樣要加入玻璃的背景副本。當漣漪經過選單後方時,它會先成為背景的一部分,再被玻璃曲面折射,而不是直接蓋在玻璃上方。兩者的空間關係正確後,玻璃才真正像是放在場景前方。
這 30 天,我們從 Vue 的生命週期與 DOM 操作開始,逐步學習 GSAP 動畫、時間軸、視差捲動、Canvas、WebGL、GLSL Shader、光線與材質,再進入 Three.js 的模型載入、貼圖、物理模擬、產品運鏡、粒子、漣漪和折射效果;最後把這些技術整合成一個可互動的 3D 產品展示網站。這段過程真的學到了很多,也是在實際動手後才發現,每解決一個問題,就會看見更多值得鑽研的方向,像是 WebGL 2、WebGPU,以及更多即時圖形技術。希望未來能夠繼續精進,共勉之~