- Memperkenalkan cara mereplikasi efek Liquid Glass yang diperkenalkan Apple di WWDC 2025 di web dengan CSS, SVG, dan perhitungan pembiasan berbasis fisika
- Menjelaskan prinsip fenomena pembiasan serta proses penggambaran permukaan kaca dan simulasi pembiasan menggunakan Hukum Snell
- Menggunakan SVG displacement map untuk membuat bidang vektor perpindahan yang cocok untuk rendering, dan mendemonstrasikan bahwa ini dapat diterapkan ke komponen UI nyata
- Di Chrome, filter SVG dapat digunakan sebagai backdrop-filter, dan ditunjukkan contoh penerapannya pada berbagai elemen UI (kaca pembesar, switch, player, dll.)
- Implementasi efek real-time dimungkinkan, tetapi ada masalah lintas-browser dan keterbatasan performa, serta disebutkan rencana open-source ke depannya
Pengenalan
Apple pertama kali memperkenalkan efek Liquid Glass pada WWDC bulan Juni 2025. Efek ini membuat elemen antarmuka tampak seperti kaca refraktif yang melengkung, sehingga memberikan pengalaman visual yang menyerupai permukaan kaca sungguhan. Artikel ini membahas praktik membuat efek serupa di lingkungan web melalui CSS, SVG displacement map, dan perhitungan pembiasan berbasis fisika. Tujuannya bukan implementasi yang sepenuhnya sempurna, melainkan proof of concept yang dapat dikembangkan dengan mereproduksi karakteristik utama seperti pembiasan dan highlight pantulan. Penjelasan dimulai dari prinsip dasar bagaimana cahaya dibiaskan saat melewati material yang berbeda, lalu membangun efeknya langkah demi langkah. Demo interaktif yang disediakan di bagian akhir saat ini hanya berfungsi normal di Chrome.
Memahami Fenomena Pembiasan
Pembiasan adalah fenomena ketika arah rambat cahaya berubah saat berpindah dari satu material ke material lain. Hal ini terjadi karena kecepatan cahaya berbeda pada tiap material, dan hubungan antara sudut datang serta sudut bias dapat dinyatakan dengan Hukum Snell:
- n1 * sin(θ1) = n2 * sin(θ2)
- n1: indeks bias medium pertama
- θ1: sudut datang
- n2: indeks bias medium kedua
- θ2: sudut bias
Hal yang dapat diamati pada diagram interaktif:
- Jika indeks bias kedua medium sama, cahaya akan terus lurus tanpa pembiasan
- Jika medium kedua memiliki indeks bias lebih tinggi, cahaya dibiaskan ke arah normal
- Jika medium kedua memiliki indeks bias lebih rendah, cahaya membelok menjauh, dan dalam kasus tertentu dapat terjadi pemantulan total internal
- Jika cahaya datang tegak lurus terhadap permukaan, ia tetap bergerak lurus terlepas dari indeks biasnya
Batasan proyek ini
Untuk membatasi kompleksitas dan menyederhanakan algoritme, digunakan kondisi berikut:
- Indeks bias medium luar adalah 1 (udara)
- Material kaca di bagian dalam menggunakan 1.5 (kaca umum)
- Peristiwa pembiasan hanya dihitung satu kali (mengabaikan pembiasan saat keluar)
- Cahaya datang selalu tegak lurus terhadap bidang latar
- Semua objek berupa bentuk 2D dan hanya menggunakan bentuk lingkaran (bisa diperluas ke persegi panjang, dll., tetapi memerlukan perhitungan tambahan)
- Tidak ada celah antara objek dan bidang latar
- Dengan kondisi ini, semua sinar dapat dihitung secara sederhana menggunakan Hukum Snell
Membuat Permukaan Kaca
Untuk mengimplementasikan efek Liquid Glass, penampang kaca virtual (lensa atau panel melengkung) perlu didefinisikan sebagai fungsi matematika.
Fungsi permukaan
Permukaan kaca didefinisikan dengan surface function, yang menyatakan ketebalan dari tepi hingga bagian dalam yang datar
- Nilai input fungsi 0: bagian luar, 1: ujung bezel (awal bidang datar)
- Dari turunan ketebalan di tiap titik, diperoleh vektor normal permukaan
const height = f(distanceFromSide);
const delta = 0.001;
const y1 = f(distanceFromSide - delta);
const y2 = f(distanceFromSide + delta);
const derivative = (y2 - y1) / (2 * delta);
const normal = { x: -derivative, y: 1 };
Jenis utama fungsi permukaan
- Convex Circle: y = sqrt((1 - (1 - x))^2)
- Bentuk busur lingkaran sederhana, cepat menjadi datar ke arah dalam sehingga tepi pembiasannya terlihat jelas
- Convex Squircle: y = ((1 - (1 - x))^4)^(1/4)
- Bentuk yang sering digunakan Apple, batas antara kurva dan bidang datar lebih halus sehingga efeknya tetap alami saat diperbesar
- Concave: y = 1 - Convex(x)
- Bentuk cekung (kebalikan cembung), cahaya dibiaskan ke luar batas objek sehingga memerlukan sampling luar
- Lip: y = mix(Convex(x), Concave(x), Smootherstep(x))
- Struktur gabungan dengan lip yang menonjol di tepi dan lekukan dangkal di tengah
Keempat fungsi ini saja sudah cukup untuk membandingkan perbedaan pembiasan berdasarkan bentuk permukaan secara efektif.
Simulasi
Jalur pembiasan sinar cahaya disimulasikan untuk tiap fungsi permukaan agar perbedaan efek nyatanya dapat divisualisasikan.
- Bentuk cembung (Convex) mengikat jalur cahaya ke dalam, sedangkan cekung (Concave) mendorongnya ke luar
- Liquid Glass milik Apple sebagian besar menyukai bentuk cembung (dengan pengecualian seperti Switch)
- Panah pada latar diberi warna berdasarkan magnitudo jumlah pembiasan (perpindahan)
- Pada jarak yang sama dari batas kiri dan kanan, perpindahannya sama sehingga dapat digunakan ulang secara efisien
Membuat Bidang Vektor Perpindahan
Dibangun sebuah bidang vektor yang merepresentasikan arah dan besar perpindahan cahaya di tiap posisi pada seluruh permukaan kaca
- Pada bentuk lingkaran, perpindahan selalu bergerak ke arah normal berdasarkan batas
Menghitung besar perpindahan lebih dulu
- Karena besar perpindahan simetris untuk tiap jarak dari batas, nilainya dapat dihitung lebih dulu per satuan radius dan disimpan dalam array
- Di 2D, perhitungan hanya dilakukan sekali (simulasi 127 sinar), lalu diputar terhadap sumbu z untuk membentuk seluruh bidang
Normalisasi vektor
Agar vektor bisa digunakan dalam displacement map, dilakukan normalisasi (skala maksimum 1.0)
- Vektor lain dinormalisasi dengan membagi terhadap nilai perpindahan maksimum
const maximumDisplacement = Math.max(...displacementMagnitudes);
displacementVector_normalized = {
angle: normalAtBorder,
magnitude: magnitude / maximumDisplacement,
};
Dalam SVG displacement map, saat dikonversi kembali ke satuan piksel nyata, nilai perpindahan maksimum dikalikan lagi lewat scale untuk memulihkan ukuran aslinya.
SVG Displacement Map
Untuk menerapkan hasil perhitungan pembiasan matematis ke rendering browser secara nyata, digunakan SVG displacement map
- Tiap kanal pada
<feDisplacementMap />(RGBA, 8-bit) dapat menangani sumbu perpindahan X dan Y masing-masing - Tiap kanal memiliki nilai 0~255, dan 128 berarti netral (tanpa perpindahan)
- displacement map harus dikonversi menjadi gambar
<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={scale}
xChannelSelector="R"
yChannelSelector="G"
/>
</filter>
</svg>
Scale
Nilai kanal Red(X) dan Green(Y) dipetakan ke rentang [−1, 1]
- Lalu dikalikan dengan perpindahan maksimum dalam satuan piksel melalui properti
scaleuntuk menghasilkan rendering nyata scaledapat dianimasikan untuk mengatur intensitas efek
Konversi vektor → nilai Red/Green
- Vektor perpindahan (sudut, besar) diubah ke koordinat kartesius x dan y, lalu dipetakan ke rentang 0~255 dengan 128 sebagai titik netral
const x = Math.cos(angle) * magnitude;
const y = Math.sin(angle) * magnitude;
const result = {
r: 128 + x * 127,
g: 128 + y * 127,
b: 128,
a: 255,
};
Gambar yang telah selesai dapat digunakan sebagai displacement map untuk filter SVG.
Playground
Di Playground interaktif, pengguna dapat mengubah bentuk permukaan, ketebalan bezel, ketebalan kaca, effect scale, dan lainnya secara real-time untuk merasakan perubahan pada bidang pembiasan, displacement map, dan hasil rendering akhir.
Specular Highlight
Terakhir, ditambahkan specular highlight (highlight tepi terang pada permukaan kaca)
- Implementasi Apple menggunakan pendekatan rim light (cahaya tepi), di mana intensitas kecerahan berubah sesuai normal permukaan dan sudut sumber cahaya
Menggabungkan Pembiasan dan Specular Highlight
Pada filter SVG akhir, displacement map dan gambar specular highlight masing-masing dimuat dengan <feImage /> lalu digabungkan dengan <feBlend /> untuk menghasilkan efek final
- Berbagai visual dapat dibuat dengan menyesuaikan parameter filter
Menggunakan filter SVG sebagai backdrop-filter
- Agar efek Liquid Glass benar-benar bisa diterapkan pada komponen UI, diperlukan dukungan Chrome terhadap
backdrop-filter: url(#...) - Ukuran gambar untuk
backdrop-filtertidak otomatis disesuaikan, sehingga displacement map yang sesuai ukuran elemen harus disiapkan
.glass-panel {
backdrop-filter: url(#liquidGlassFilterId);
}
Penerapan pada komponen UI nyata
Dicontohkan penerapan pada komponen UI yang realistis berdasarkan refraction dan displacement map yang telah dihitung
- Hanya Chrome yang dapat memproses filter SVG sebagai
backdrop-filter - Contoh-contoh ini bukan komponen produksi sungguhan, melainkan demonstrasi bagaimana efek Liquid Glass dapat diterapkan ke beragam UI
Kaca pembesar
- Menggunakan pembiasan dan zoom di kedua sisi, serta dua displacement map
- Memberi efek interaktif melalui bayangan dan penyesuaian skala
- Bentuk lensa dapat diubah dengan drag untuk mengamati jalur pembiasan
- Ditambahkan specular highlight yang halus
Searchbox
- Efek Liquid Glass diterapkan pada bentuk kotak input standar
Switch
- Menggunakan lip bezel sehingga bagian luar cembung dan bagian dalam cekung
- Hanya slider di tengah yang berada dalam keadaan diperbesar/diperkecil, sementara tepinya menerapkan pembiasan gambar di dalam
Slider
- Menggunakan convex bezel, menampilkan nilai saat ini apa adanya melalui kaca, dan menerapkan pembiasan latar di kedua sisi
Music Player
-
Meniru gaya panel Liquid Glass milik Apple Music
-
Convex bezel dan specular highlight yang halus memberi kesan dimensional
-
Menggunakan iTunes Search API untuk memuat album art dan informasi seperti judul lagu
-
(Menyediakan informasi judul lagu dan album dalam bentuk daftar)
Kesimpulan
Prototipe ini menyederhanakan konsep Liquid Glass milik Apple menjadi efek pembiasan real-time dan highlight sederhana. Ini praktis hanya dapat berjalan di browser berbasis Chromium (atau Electron), sementara di browser lain dapat digantikan dengan layer blur.
Ini adalah implementasi eksperimental, dan regenerasi displacement map untuk setiap perubahan shape/size sangat tidak efisien (hanya beberapa parameter seperti filter scale yang dapat dianimasikan).
Penulis sedang mempertimbangkan rilis open-source di masa mendatang, serta menyatakan minat pada optimasi dan perapian kode.
Belum ada komentar.