Saya sangat senang ketika tim Google Data Arts menghubungi Moniker dan saya untuk bekerja sama guna menjelajahi kemungkinan yang diperkenalkan oleh WebVR. Saya telah melihat karya yang dihasilkan tim mereka selama bertahun-tahun dan project mereka selalu menarik perhatian saya. Kolaborasi kami menghasilkan Dance Tonite, pengalaman tarian VR yang terus berubah dengan LCD Soundsystem dan penggemarnya. Berikut cara kami melakukannya.
Konsep
Kami memulai dengan mengembangkan serangkaian prototipe menggunakan WebVR, standar terbuka yang memungkinkan Anda memasuki VR dengan mengunjungi situs menggunakan browser. Tujuannya adalah memudahkan semua orang mendapatkan pengalaman VR, apa pun perangkat yang Anda miliki.
Kami mempertimbangkan hal ini. Apa pun yang kita buat akan berfungsi di semua jenis VR, mulai dari headset VR yang berfungsi dengan ponsel seperti Daydream View Google, Cardboard, dan Gear VR Samsung hingga sistem skala ruangan seperti HTC VIVE dan Oculus Rift yang mencerminkan gerakan fisik Anda di lingkungan VR. Mungkin yang paling penting, kami merasa akan sesuai dengan semangat web untuk membuat sesuatu yang juga berfungsi bagi semua orang yang tidak memiliki perangkat VR.
1. Motion capture DIY
Karena ingin melibatkan pengguna secara kreatif, kami mulai mencari kemungkinan partisipasi dan ekspresi diri menggunakan VR. Kami terkesan dengan seberapa halus Anda dapat bergerak dan melihat-lihat di VR, dan seberapa banyak fidelitas yang ada. Ini memberi kami ide. Daripada meminta pengguna untuk melihat atau membuat sesuatu, bagaimana jika mereka merekam gerakan mereka?
Kami membuat prototipe yang merekam posisi kacamata VR dan pengontrol saat menari. Kami mengganti posisi yang direkam dengan bentuk abstrak dan kagum dengan hasilnya. Hasilnya sangat manusiawi dan berisi begitu banyak kepribadian. Kami segera menyadari bahwa kita dapat menggunakan WebVR untuk melakukan perekaman gerakan murah di rumah.
Dengan WebVR, developer memiliki akses ke posisi kepala dan orientasi pengguna melalui objek VRPose. Nilai ini diperbarui setiap frame oleh hardware VR sehingga kode Anda dapat merender frame baru dari sudut pandang yang benar. Melalui GamePad API dengan WebVR, kita juga dapat mengakses posisi/orientasi pengontrol pengguna melalui objek GamepadPose. Kita cukup menyimpan semua nilai posisi dan orientasi ini setiap frame, sehingga membuat "rekaman" gerakan pengguna.
2. Minimalisme & kostum
Dengan peralatan VR skala ruangan saat ini, kita dapat melacak tiga titik tubuh pengguna: kepala dan dua tangan. Dalam Dance Tonite, kami ingin tetap berfokus pada kemanusiaan dalam gerakan 3 titik ini di ruang. Untuk mencapai hal ini, kami mendorong estetika seminimal mungkin untuk berfokus pada gerakan. Kami menyukai ide untuk memanfaatkan otak orang.
Video ini yang menunjukkan karya Psikolog Swedia Gunnar Johansson adalah salah satu contoh yang kami rujuk saat mempertimbangkan untuk menyederhanakan sesuatu sebanyak mungkin. Gambar ini menunjukkan bagaimana titik putih mengambang langsung dikenali sebagai objek saat dilihat dalam gerakan.
Secara visual, kami terinspirasi oleh ruangan berwarna dan kostum geometris dalam rekaman Margarete Hastings tahun 1970 yang menampilkan kembali Triadic Ballet karya Oskar Schlemmer.
Sementara alasan Schlemmer memilih kostum geometris abstrak adalah untuk membatasi gerakan penarinya menjadi seperti boneka & boneka tali, kami memiliki tujuan yang berlawanan untuk Dance Tonite.
Kami akhirnya mendasarkan pilihan bentuk pada seberapa banyak informasi yang disampaikannya dengan rotasi. Bola terlihat sama, apa pun cara memutarnya, tetapi kerucut benar-benar menunjuk ke arah yang dilihat dan terlihat berbeda dari depan daripada belakang.
3. Pedal loop untuk gerakan
Kami ingin menampilkan rekaman orang dalam jumlah besar yang menari dan bergerak bersama satu sama lain. Untuk melakukannya secara live, hal ini tidak memungkinkan karena perangkat VR tidak tersedia dalam jumlah yang cukup besar. Namun, kami tetap ingin memiliki sekelompok orang yang bereaksi satu sama lain melalui gerakan. Kami teringat akan performa rekursif Norman McClaren dalam karyanya yang berjudul "Canon" di tahun 1964.
Performa McClaren menampilkan serangkaian gerakan yang sangat terkoreografi yang mulai berinteraksi satu sama lain setelah setiap loop. Sama seperti pedal loop dalam musik, tempat musisi melakukan jam session dengan diri mereka sendiri dengan menempatkan berbagai bagian musik live, kami ingin melihat apakah kami dapat menciptakan lingkungan tempat pengguna dapat berimprovisasi secara bebas dengan versi pertunjukan yang lebih longgar.
4. Kamar yang saling terhubung
Seperti kebanyakan musik, trek LCD Soundsystem dibuat menggunakan pengukuran waktu yang tepat. Lagu mereka, Tonite, yang ditampilkan dalam project kami, menampilkan ukuran yang berdurasi tepat 8 detik. Kami ingin pengguna membuat performa untuk setiap loop 8 detik di trek. Meskipun ritme ukuran ini tidak berubah, konten musiknya berubah. Seiring lagu berjalan, ada momen dengan instrumen dan vokal yang berbeda yang dapat direspons performer dengan cara yang berbeda. Setiap ukuran ini dinyatakan sebagai ruangan, tempat orang dapat membuat performa yang sesuai.
Pengoptimalan untuk performa: jangan lepaskan frame
Membuat pengalaman VR multi-platform yang berjalan di satu codebase dengan performa optimal untuk setiap perangkat atau platform bukanlah hal yang mudah.
Saat menggunakan VR, salah satu hal yang paling membuat mual yang dapat Anda alami disebabkan oleh frekuensi frame yang tidak selaras dengan gerakan Anda. Jika Anda memutar kepala, tetapi visual yang dilihat mata tidak cocok dengan gerakan yang dirasakan telinga bagian dalam, hal ini akan menyebabkan perut berputar secara instan. Oleh karena itu, kita perlu menghindari penundaan kecepatan frame yang besar. Berikut beberapa pengoptimalan yang kami terapkan.
1. Geometri buffer instance
Karena seluruh project kita hanya menggunakan beberapa objek 3D, kita bisa mendapatkan
peningkatan performa yang sangat besar dengan menggunakan Instanced Buffer Geometry. Pada dasarnya, ini
memungkinkan Anda mengupload objek ke GPU satu kali dan menggambar sebanyak mungkin "instance"
objek tersebut sesuai keinginan dalam satu panggilan gambar. Di Dance Tonite, kita hanya memiliki 3
objek berbeda (kerucut, silinder, dan ruangan dengan lubang), tetapi berpotensi
memiliki ratusan salinan objek tersebut. Instance Buffer Geometry adalah bagian dari
ThreeJS,
tetapi kami menggunakan fork eksperimental dan sedang dikerjakan
Dusan Bosnjak yang mengimplementasikan
THREE.InstanceMesh
, yang membuat penggunaan Instanced Buffer Geometry jauh
lebih mudah.
2. Menghindari pengumpulan sampah
Seperti banyak bahasa skrip lainnya, JavaScript otomatis mengosongkan memori dengan mengetahui objek mana yang dialokasikan dan tidak digunakan lagi. Proses ini disebut pembersihan sampah memori.
Developer tidak memiliki kontrol atas waktu terjadinya hal ini. Pembersih sampah memori dapat muncul di depan pintu kita kapan saja dan mulai mengosongkan sampah, yang mengakibatkan frame turun seiring waktu.
Solusinya adalah dengan menghasilkan sampah sesedikit mungkin dengan mendaur ulang objek. Daripada membuat objek vektor baru untuk setiap penghitungan, kita menandai objek awal untuk digunakan kembali. Karena kami berpegang padanya dengan memindahkan referensi kami ke luar cakupan kami, referensi tersebut tidak ditandai untuk dihapus.
Misalnya, berikut kode kami untuk mengonversi matriks lokasi kepala
dan tangan pengguna menjadi array nilai posisi/rotasi yang kita simpan di setiap frame. Dengan
menggunakan kembali SERIALIZE_POSITION
, SERIALIZE_ROTATION
, dan SERIALIZE_SCALE
, kita
menghindari alokasi memori dan pembersihan sampah memori yang akan terjadi jika kita
membuat objek baru setiap kali fungsi dipanggil.
const SERIALIZE_POSITION = new THREE.Vector3();
const SERIALIZE_ROTATION = new THREE.Quaternion();
const SERIALIZE_SCALE = new THREE.Vector3();
export const serializeMatrix = (matrix) => {
matrix.decompose(SERIALIZE_POSITION, SERIALIZE_ROTATION, SERIALIZE_SCALE);
return SERIALIZE_POSITION.toArray()
.concat(SERIALIZE_ROTATION.toArray())
.map(compressNumber);
};
3. Membuat serial gerakan & pemutaran progresif
Untuk menangkap pergerakan pengguna di VR, kami perlu melakukan serialisasi posisi dan rotasi headset dan pengontrol mereka, serta mengupload data ini ke server kami. Kita mulai mengambil matriks transformasi lengkap untuk setiap frame. Ini berperforma baik, tetapi dengan 16 angka yang dikalikan dengan 3 posisi masing-masing pada 90 frame per detik, hal ini menyebabkan file yang sangat besar sehingga waktu tunggu lama saat mengupload dan mendownload data. Dengan hanya mengekstrak data posisi dan rotasi dari matriks transformasi, kita dapat menurunkan nilai ini dari 16 menjadi 7.
Karena pengunjung di web sering kali mengklik link tanpa mengetahui dengan pasti apa yang akan mereka lihat, kita perlu menampilkan konten visual dengan cepat atau mereka akan keluar dalam hitungan detik.
Karena alasan ini, kami ingin memastikan project dapat mulai diputar sesegera mungkin. Awalnya, kita menggunakan JSON sebagai format untuk memuat data gerakan. Masalahnya adalah kita harus memuat file JSON lengkap sebelum kita dapat mengurainya. Tidak terlalu progresif.
Agar project seperti Dance Tonite tetap ditampilkan dengan kecepatan frame tertinggi, browser hanya memiliki sedikit waktu setiap frame untuk penghitungan JavaScript. Jika Anda memerlukan waktu terlalu lama, animasi akan mulai tersendat. Awalnya, kami mengalami gangguan karena file JSON yang besar ini didekode oleh browser.
Kami telah menemukan format data streaming yang mudah berbasis yang disebut NDJSON atau JSON yang dibatasi Newline. Trik di sini adalah membuat file dengan serangkaian string JSON yang valid, masing-masing di baris sendiri. Hal ini memungkinkan Anda mengurai file saat dimuat, sehingga kami dapat menampilkan performa sebelum dimuat sepenuhnya.
Berikut tampilan bagian salah satu rekaman kami:
{"fps":15,"count":1,"loopIndex":"1","hideHead":false}
[-464,17111,-6568,-235,-315,-44,9992,-3509,7823,-7074, ... ]
[-583,17146,-6574,-215,-361,-38,9991,-3743,7821,-7092, ... ]
[-693,17158,-6580,-117,-341,64,9993,-3977,7874,-7171, ... ]
[-772,17134,-6591,-93,-273,205,9994,-4125,7889,-7319, ... ]
[-814,17135,-6620,-123,-248,408,9988,-4196,7882,-7376, ... ]
[-840,17125,-6644,-173,-227,530,9982,-4174,7815,-7356, ... ]
[-868,17120,-6670,-148,-183,564,9981,-4069,7732,-7366, ... ]
...
Dengan menggunakan NDJSON, kita dapat menyimpan representasi data dari setiap frame performa sebagai string. Kita dapat menunggu hingga mencapai waktu yang diperlukan, sebelum mendekodenya menjadi data posisi, sehingga memperluas pemrosesan yang diperlukan dari waktu ke waktu.
4. Gerakan interpolasi
Karena kita berharap untuk menampilkan antara 30 hingga 60 performa yang berjalan secara bersamaan, kami perlu menurunkan kecepatan data lebih jauh dari yang sudah ada. Tim Data Arts mengatasi masalah yang sama dalam project Virtual Art Sessions mereka, tempat mereka memutar rekaman artis yang melukis di VR menggunakan Kuas Virtual. Mereka mengatasinya dengan membuat versi perantara data pengguna dengan kecepatan frame yang lebih rendah dan melakukan interpolasi di antara frame saat memutarnya. Kami terkejut karena hampir tidak dapat melihat perbedaan antara rekaman yang diinterpolasi yang berjalan pada 15 FPS dibandingkan dengan rekaman asli 90 FPS.
Untuk melihatnya sendiri, Anda dapat memaksa Dance Tonite untuk memutar data dengan berbagai
kecepatan menggunakan string kueri ?dataRate=
. Anda dapat menggunakannya untuk membandingkan
gerakan yang direkam pada 90 frame per detik, 45
frame per detik, atau 15 frame per
detik.
Untuk posisi, kita melakukan interpolasi linear antara keyframe sebelumnya dan berikutnya, berdasarkan seberapa dekat kita dalam waktu antara keyframe (rasio):
const { x: x1, y: y1, z: z1 } = getPosition(previous, performanceIndex, limbIndex);
const { x: x2, y: y2, z: z2 } = getPosition(next, performanceIndex, limbIndex);
interpolatedPosition = new THREE.Vector3();
interpolatedPosition.set(
x1 + (x2 - x1) * ratio,
y1 + (y2 - y1) * ratio,
z1 + (z2 - z1) * ratio
);
Untuk orientasi, kami melakukan interpolasi linier sferikal (slerp) antar-keyframe. Orientasi disimpan sebagai Kuaternion.
const quaternion = getQuaternion(previous, performanceIndex, limbIndex);
quaternion.slerp(
getQuaternion(next, performanceIndex, limbIndex),
ratio
);
5. Menyinkronkan gerakan dengan musik
Untuk mengetahui frame animasi yang direkam yang akan diputar, kita perlu mengetahui waktu musik saat ini hingga milidetik. Ternyata, meskipun elemen HTML Audio cocok untuk memuat dan memutar suara secara progresif, properti waktu yang disediakan tidak berubah secara sinkron dengan loop frame browser. Selalu ada sedikit perbedaan. Terkadang sebagian detik terlalu awal, terkadang terlalu lambat.
Hal ini menyebabkan gangguan pada rekaman tarian yang indah, yang ingin kita hindari dengan segala cara. Untuk mengatasinya, kita menerapkan timer kita sendiri di JavaScript. Dengan cara ini, kita dapat yakin bahwa jumlah waktu yang berubah di antara frame adalah persis jumlah waktu yang telah berlalu sejak frame terakhir. Setiap kali timer tidak sinkron dengan musik lebih dari 10 md, kita akan menyinkronkannya kembali.
6. Penghapusan dan kabut
Setiap cerita membutuhkan akhir yang baik dan kami ingin melakukan sesuatu yang mengejutkan bagi pengguna yang berhasil sampai ke akhir pengalaman kami. Saat Anda meninggalkan ruangan terakhir, Anda memasuki lanskap kerucut dan silinder yang tenang. "Apakah ini sudah selesai?", Anda bertanya-tanya. Saat Anda bergerak lebih jauh ke lapangan, tiba-tiba nada musik menyebabkan berbagai kelompok kerucut dan silinder terbentuk menjadi penari. Anda berada di tengah-tengah pesta besar. Kemudian, saat musik berhenti tiba-tiba, semuanya jatuh ke tanah.
Meskipun hal ini terasa luar biasa sebagai penonton, hal ini memperkenalkan beberapa hambatan performa yang harus diselesaikan. Perangkat VR skala ruangan dan rig game kelas atas berperforma sempurna dengan 40 performa tambahan ganjil yang diperlukan untuk akhir baru kami. Tapi kecepatan {i>frame<i} pada perangkat seluler tertentu telah berkurang setengahnya.
Untuk mengatasi hal ini, kami memperkenalkan kabut. Setelah jarak tertentu semuanya perlahan menjadi hitam. Karena kita tidak perlu menghitung atau menggambar yang tidak terlihat, kita akan menghapus performa di ruangan yang tidak terlihat dan ini memungkinkan kita untuk menghemat pekerjaan untuk CPU & GPU. Namun, bagaimana cara menentukan jarak yang tepat?
Beberapa perangkat dapat menangani apa pun yang Anda berikan, dan perangkat lainnya lebih terbatas. Kami memilih untuk menerapkan skala geser. Dengan terus mengukur jumlah frame per detik, kita dapat menyesuaikan jarak kabut. Selama kecepatan frame berjalan lancar, kita akan mencoba melakukan lebih banyak pekerjaan render dengan mendorong kabut. Jika kecepatan frame tidak berjalan cukup lancar, kita akan mendekatkan kabut sehingga kita dapat melewati performa rendering dalam kegelapan.
// this is called every frame
// the FPS calculation is based on stats.js by @mrdoob
tick: (interval = 3000) => {
frames++;
const time = (performance || Date).now();
if (prevTime == null) prevTime = time;
if (time > prevTime + interval) {
fps = Math.round((frames * 1000) / (time - prevTime));
frames = 0;
prevTime = time;
const lastCullDistance = settings.cullDistance;
// if the fps is lower than 52 reduce the cull distance
if (fps <= 52) {
settings.cullDistance = Math.max(
settings.minCullDistance,
settings.cullDistance - settings.roomDepth
);
}
// if the FPS is higher than 56, increase the cull distance
else if (fps > 56) {
settings.cullDistance = Math.min(
settings.maxCullDistance,
settings.cullDistance + settings.roomDepth
);
}
}
// gradually increase the cull distance to the new setting
cullDistance = cullDistance * 0.95 + settings.cullDistance * 0.05;
// mask the edge of the cull distance with fog
viewer.fog.near = cullDistance - settings.roomDepth;
viewer.fog.far = cullDistance;
}
Berbagai pilihan konten untuk semuanya: membuat VR untuk web
Mendesain dan mengembangkan pengalaman asimetris multi-platform berarti memperhitungkan kebutuhan setiap pengguna, bergantung pada perangkat mereka. Dan dengan setiap keputusan desain, kita perlu melihat bagaimana hal itu dapat memengaruhi pengguna lain. Bagaimana cara memastikan bahwa apa yang Anda lihat di VR sama menariknya dengan tanpa VR, dan sebaliknya?
1. Bola kuning
Jadi, pengguna VR skala ruangan akan membuat performa, tetapi bagaimana pengguna perangkat VR seluler (seperti Cardboard, Daydream View, atau Samsung Gear) akan merasakan project ini? Untuk ini, kami memperkenalkan elemen baru ke lingkungan kita: bola kuning.
Saat menonton project dalam VR, Anda melakukannya dari sudut pandang bola kuning. Saat Anda berpindah dari satu ruangan ke ruangan lainnya, para penari akan bereaksi terhadap kehadiran Anda. Mereka memberi isyarat kepada Anda, menari di sekitar Anda, melakukan gerakan lucu di belakang Anda, dan bergerak dengan cepat agar tidak menabrak Anda. Lingkaran kuning selalu menjadi pusat perhatian.
Alasannya adalah saat merekam pertunjukan, bola kuning akan bergerak di tengah ruangan yang selaras dengan musik dan berputar kembali. Posisi bola memberi penampil gambaran tentang posisi mereka dalam waktu dan berapa banyak waktu yang tersisa dalam loop mereka. Hal ini memberikan fokus alami bagi mereka untuk membangun performa.
2. Sudut pandang lain
Kami tidak ingin mengabaikan pengguna tanpa VR, terutama karena mereka kemungkinan akan menjadi penonton terbesar kami. Daripada membuat pengalaman VR palsu, kami ingin memberikan pengalaman tersendiri kepada perangkat berbasis layar. Kami memiliki ide untuk menampilkan performa dari atas dari perspektif isometrik. Perspektif ini memiliki sejarah yang kaya dalam {i>game<i} komputer. Game ini pertama kali digunakan di Zaxxon, game tembak-tembakan antariksa dari tahun 1982. Jika pengguna VR sudah mendalaminya, perspektif isometrik memberikan tampilan mirip dewa tentang aksi tersebut. Kami memilih untuk sedikit menskalakan model, sehingga memberikan sentuhan estetika rumah boneka.
3. Bayangan: palsukan sampai Anda mewujudkannya
Kami mendapati bahwa beberapa pengguna kami kesulitan melihat kedalaman dalam titik pandang isometrik kami. Saya cukup yakin karena alasan inilah Zaxxon juga salah satu game komputer pertama dalam sejarah yang memproyeksikan bayangan dinamis di bawah objek terbangnya.
Ternyata membuat bayangan dalam 3D itu sulit. Terutama untuk perangkat yang terbatas seperti ponsel. Awalnya, kami harus membuat keputusan sulit untuk menghapusnya dari persamaan, tetapi setelah meminta saran kepada penulis Three.js dan hacker demo berpengalaman Mr doob, ia mendapatkan ide baru untuk… memalsukannya.
Daripada harus menghitung bagaimana setiap objek mengambang mengaburkan cahaya sehingga dapat melemparkan bayangan dengan bentuk yang berbeda-beda, kita akan menggambar gambar tekstur buram melingkar yang sama di bawah masing-masing objek. Karena visual kami tidak mencoba meniru kenyataan sejak awal, kami mendapati bahwa kita dapat mengabaikannya dengan cukup mudah hanya dengan beberapa penyesuaian. Ketika objek mendekati permukaan tanah, teksturnya menjadi lebih gelap dan mengecil. Ketika mereka bergerak ke atas, kita membuat teksturnya lebih transparan dan lebih besar.
Untuk membuatnya, kami menggunakan tekstur ini dengan gradien putih ke hitam yang lembut (tanpa transparansi alfa). Kita menetapkan materi sebagai transparan dan menggunakan penggabungan subtraktif. Hal ini membantu mereka menyatu dengan baik saat tumpang tindih:
function createShadow() {
const texture = new THREE.TextureLoader().load(shadowTextureUrl);
const material = new THREE.MeshLambertMaterial({
map: texture,
transparent: true,
side: THREE.BackSide,
depthWrite: false,
blending: THREE.SubtractiveBlending,
});
const geometry = new THREE.PlaneBufferGeometry(0.5, 0.5, 1, 1);
const plane = new THREE.Mesh(geometry, material);
return plane;
}
4. Hadir
Dengan mengklik kepala pemain, pengunjung tanpa VR dapat menonton hal-hal dari sudut pandang penari. Dari sudut ini, banyak detail kecil akan terlihat jelas. Untuk menjaga agar penampilan mereka tetap sinkron, penari saling melihat dengan cepat. Saat bola memasuki ruangan, Anda melihat mereka dengan gugup melihat ke arahnya. Meskipun sebagai penonton, Anda tidak dapat memengaruhi gerakan ini, gerakan tersebut memang menyampaikan perasaan imersi dengan sangat baik. Sekali lagi, kami lebih memilih melakukan hal ini daripada menyajikan versi VR palsu yang membosankan dan dikontrol mouse kepada pengguna.
5. Membagikan rekaman
Kami tahu betapa bangganya Anda saat berhasil merekam 20 lapisan penampil yang bereaksi satu sama lain dengan koreografi yang rumit. Kita tahu pengguna mungkin ingin menunjukkannya kepada teman mereka. Tapi, gambar diam dari prestasi ini tidak cukup untuk berkomunikasi. Namun, kami ingin memungkinkan pengguna membagikan video pertunjukan mereka. Sebenarnya, mengapa tidak GIF? Animasi kami memiliki bayangan datar, yang cocok untuk palet warna terbatas dalam format ini.
Kami beralih ke GIF.js, library JavaScript yang memungkinkan Anda mengenkode GIF animasi dari dalam browser. Web worker ini akan memindahkan enkode frame ke web worker yang dapat berjalan di latar belakang sebagai proses terpisah, sehingga dapat memanfaatkan beberapa prosesor yang bekerja secara berdampingan.
Sayangnya, dengan jumlah frame yang kami butuhkan untuk animasi, proses encodingnya masih terlalu lambat. GIF dapat membuat file kecil dengan menggunakan palet warna terbatas. Kami mendapati bahwa sebagian besar waktu dihabiskan untuk menemukan warna terdekat untuk setiap piksel. Kami dapat mengoptimalkan proses ini sepuluh kali lipat dengan meng-hack pintasan kecil: jika warna piksel sama dengan yang terakhir, gunakan warna yang sama dari palet seperti sebelumnya.
Sekarang kita memiliki encoding yang cepat, tetapi ukuran file GIF yang dihasilkan terlalu besar. Format GIF memungkinkan Anda menunjukkan cara setiap frame ditampilkan di atas frame terakhir dengan menentukan metode penghapusannya. Untuk mendapatkan file yang lebih kecil, alih-alih mengupdate setiap piksel pada setiap frame, kita hanya mengupdate piksel yang berubah. Meskipun memperlambat proses encoding lagi, hal ini memang mengurangi ukuran file dengan baik.
6. Dasar yang kuat: Google Cloud & Firebase
Backend situs “konten buatan pengguna” sering kali rumit dan rapuh, tetapi kami menciptakan sistem yang sederhana dan andal berkat Google Cloud dan Firebase. Saat mengunggah tarian baru ke sistem, penampil akan diautentikasi secara anonim oleh Firebase Authentication. Mereka diberi izin untuk mengupload rekaman ke ruang sementara menggunakan Cloud Storage for Firebase. Saat upload selesai, mesin klien akan memanggil pemicu HTTP Cloud Functions for Firebase menggunakan token Firebase-nya. Tindakan ini akan memicu proses server yang memvalidasi pengiriman, membuat data database, dan memindahkan rekaman ke direktori publik di Google Cloud Storage.
Semua konten publik kami disimpan dalam serangkaian file datar di Bucket Cloud Storage. Artinya, data kami dapat diakses dengan cepat di seluruh dunia dan kami tidak perlu khawatir dengan beban traffic yang tinggi yang memengaruhi ketersediaan data dengan cara apa pun.
Kami menggunakan endpoint Firebase Realtime Database dan Cloud Functions untuk membuat alat moderasi/kurasi sederhana yang memungkinkan kami menonton setiap kiriman baru dalam VR dan memublikasikan playlist baru dari perangkat apa pun.
7. Pekerja Layanan
Service worker adalah inovasi yang cukup baru yang membantu mengelola penyimpanan dalam cache aset situs. Dalam kasus kami, pekerja layanan memuat konten dengan sangat cepat untuk pengunjung yang kembali dan bahkan memungkinkan situs berfungsi secara offline. Ini adalah fitur penting karena banyak pengunjung kami yang akan menggunakan koneksi seluler dengan kualitas yang bervariasi.
Menambahkan pekerja layanan ke project sangat mudah berkat plugin webpack praktis yang menangani sebagian besar tugas berat untuk Anda. Dalam konfigurasi di bawah ini, kita menghasilkan pekerja layanan yang akan otomatis meng-cache semua file statis. File playlist terbaru akan diambil dari jaringan, jika tersedia, karena playlist akan terus diperbarui. Semua file json rekaman harus diambil dari cache jika tersedia, karena file ini tidak akan pernah berubah.
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
config.plugins.push(
new SWPrecacheWebpackPlugin({
dontCacheBustUrlsMatching: /\.\w{8}\./,
filename: 'service-worker.js',
minify: true,
navigateFallback: 'index.html',
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
runtimeCaching: [{
urlPattern: /playlist\.json$/,
handler: 'networkFirst',
}, {
urlPattern: /\/recordings\//,
handler: 'cacheFirst',
options: {
cache: {
maxEntries: 120,
name: 'recordings',
},
},
}],
})
);
Saat ini, plugin tidak menangani aset media yang dimuat secara progresif seperti
file musik, jadi kami mengatasinya dengan menetapkan header Cache-Control
Cloud Storage
pada file ini ke public, max-age=31536000
sehingga browser akan meng-cache file tersebut hingga satu tahun.
Kesimpulan
Kami senang melihat bagaimana para penampil akan menambahkan pengalaman ini dan menggunakannya sebagai alat untuk ekspresi kreatif menggunakan gerakan. Kami telah merilis semua kode open source, yang dapat Anda temukan di https://github.com/puckey/dance-tonite. Pada tahap awal VR dan terutama WebVR ini, kami tidak sabar untuk melihat arah baru yang kreatif dan tidak terduga yang akan diambil oleh media baru ini. Joget terus.