Merender Teks di WebVR

Dalam Detail

Lihat situs

Di dalam (https://with.in/) adalah platform untuk bercerita dalam realitas maya. Jadi, saat tim mendengar tentang WebVR di 2015, kami sangat tertarik dengan potensinya. Saat ini, minat tersebut berubah menjadi subdomain unik dari platform web kita, https://vr.with.in/. Siapa pun yang memiliki browser dengan VR dapat buka situs, klik tombol, dan gunakan headset untuk menikmati portofolio film VR.

Saat ini hal tersebut mencakup, tetapi tidak terbatas pada Chrome di Daydream View. Sebagai informasi di perangkat dan layar yang dipasang di kepala, lihat https://webvr.info/.

Seperti lingkungan rendering khusus virtual reality lainnya, web terutama mengandalkan representasi tiga dimensi dari adegan. Ini adegan memiliki kamera, perspektif Anda, dan sejumlah objek. Untuk membantu mengelola adegan, kamera, dan objek ini kita menggunakan pustaka yang disebut Three.js yang memanfaatkan elemen <canvas> untuk ditampilkan rendering ke GPU komputer Anda. Ada banyak add-on Three.js yang berguna untuk membuat adegan Anda dapat dilihat di WebVR. Dua utamanya adalah THREE.VREffect untuk membuat area pandang untuk setiap mata dan THREE.VRControls untuk menerjemahkan perspektif (misalnya rotasi dan posisi yang dipasang di kepala) secara meyakinkan ke dalam adegan. Ada banyak contoh cara menerapkannya. Lihat Contoh WebVR Three.js untuk memulai.

Ketika kami semakin dalam mengeksplorasi WebVR, kami menemui masalah. Jika kita melihat pada konten web, teks adalah bagian integral darinya. Meskipun mayoritas konten kami berbasis video. Jika Anda membuka Teks di dalam situs mengelilingi konten; antarmuka pengguna dan informasi tambahan tentang film atau film-film terkait dibangun dengan teks. Selain itu, semua teks ini dibuat di DOM. Dengan Eksplorasi WebVR dan https://vr.with.in/ dapat dilakukan <canvas>.

Teks yang digunakan di WebVR Teks yang digunakan di WebVR
Teks yang digunakan dalam WebVR untuk vr.with.in

Apa saja Opsi saya?

Untungnya, ada pekerjaan yang sedang dilakukan untuk mewujudkannya. Dalam penelitian kami, kita menemukan sejumlah cara yang efektif untuk merender teks dalam bentuk lingkungan pada elemen <canvas>. Di bawah ini adalah matriks dari beberapa yang kita temukan ditandai dengan pro dan kontra untuk masing-masing:

Penyelesaian Masalah Fitur Tipografi Performa Kemudahan Penerapan
Teks kanvas 2D Ya Ya Ya
Teks vektor triangulasi Ya Ya
Teks 3D yang diekstrusi Ya
Teks bitmap kolom jarak yang ditandatangani Ya Ya Ya

Keputusan Kami: Font Bitmap SDF

Kanvas 2D dengan ctx.fillText() dapat melakukan pengemasan teks, spasi huruf, dan baris tinggi, tetapi {i>overflow<i} akan terpotong, dan teks akan buram jika Anda memperbesarnya jauh. Anda dapat memperbesar ukuran tekstur kanvas, tetapi mungkin mencapai batas batas ukuran tekstur atau performa bisa menurun jika tekstur terlalu besar.

Teks 3D yang diekstrusi pada dasarnya sama dengan teks vektor triangulasi, tetapi dengan kedalaman dan mungkin bevel, sehingga memiliki geometri setidaknya dua kali lipat. Salah satu dari ini dapat bekerja dalam dosis kecil untuk judul atau logo, tetapi tidak akan berfungsi baik untuk teks dalam jumlah besar dan tidak memiliki fitur tipografi.

Alur kerja bitmap font ke SDF
Alur kerja bitmap SDF dengan font font

Font bitmap menggunakan satu segiempat (dua segitiga) per karakter, sehingga menggunakan lebih sedikit geometri dan berperforma lebih baik daripada vektor triangulasi. Gambar tersebut masih berbasis raster karena menggunakan sprite peta tekstur, tetapi dengan SDF shader pada dasarnya tidak bergantung pada resolusi sehingga terlihat lebih bagus daripada 2D tekstur kanvas. Matt DesLauriers tiga-bmfont-text juga mencakup fitur tipografi yang dapat diandalkan untuk pembungkus teks, spasi huruf, tinggi baris, dan perataan. Overflow tidak terpotong. {i>Font<i} ukurannya dikontrol melalui skala. Kita memilih rute ini karena memberi kita pilihan terbaik untuk desain dengan tetap mempertahankan performa tinggi. Sayangnya, itu tidak mudah diterapkan jadi kita akan melalui langkah-langkah tersebut dengan harapan dapat membantu pengembang yang bekerja menggunakan WebVR.

1. Membuat font bitmap (.png + .fnt)

Antarmuka Hiero
Antarmuka Hiero
Output hiero (file .fnt dan PNG Bitmap) Output hiero (file .fnt dan PNG Bitmap)
Output hiero (file .fnt dan PNG Bitmap)

Hiero adalah pengemasan font bitmap yang berjalan dengan Java. Dokumentasi Hiero tidak benar-benar menjelaskan cara menjalankannya tanpa melalui proses build yang rumit. Pertama, instal Java jika yang belum Anda lakukan. Kemudian, jika klik dua kali pada {i>runnable-hiero.jar<i} tidak berhasil buka Hiero, coba jalankan dengan perintah ini di konsol:

java -jar runnable-hiero.jar

Setelah Hiero berjalan, buka font desktop .ttf atau .otf, masukkan karakter yang ingin disertakan, ubah rendering ke Java untuk mengaktifkan efek, menambah ukurannya sehingga karakter Anda mengisi seluruh kotak cache glyph, menambahkan efek bidang jarak, menyesuaikan skala bidang jarak dan menyebarkannya. Tujuan nilai skala seperti resolusi. Semakin tinggi, semakin buram, tetapi semakin lama waktu yang dibutuhkan bagi Hiero untuk merender pratinjau. Lalu simpan font bitmap. Menghasilkan font bitmap yang terdiri dari gambar .png dan File deskripsi font AngelCode .fnt.

2. Konversi AngelCode ke JSON

Setelah font bitmap dihasilkan, kita harus memuatnya ke aplikasi JavaScript dengan Matt DesLauriers paket npm load-bmfont.

Kita dapat melakukan {i>browser<i} {i>load-bmfont<i} dan menggunakannya di bagian depan, tetapi kita sebaliknya akan berlari load-bmfont.js dengan Node untuk mengonversi dan menyimpan .fnt AngelCode Hiero ke File.json:

npm install
node load-bmfont.js
Contoh JSON output
Contoh JSON output

Sekarang kita dapat mengabaikan load-bmfont dan cukup melakukan permintaan XHR (XMLHttpRequest) pada File font .json.

var r = new XMLHttpRequest();
r.open('GET', 'fonts/roboto/bitmap/roboto-bold.json');

r.onreadystatechange = function() {
    if (r.readyState === 4 && r.status === 200) {
    setup(JSON.parse(r.responseText));
    }
};

r.send();

function setup(font) {
    // pass font into TextBitmap object
}

3. Browserifikasi tiga-bmfont-text

Setelah {i>font <i}dimuat, tiga-bmfont-teks Matt akan menangani beristirahat. Karena kita tidak menggunakan Node untuk aplikasi kita sendiri, kita akan browserify three-bmfont-text.js menjadi three-bmfont-text-bundle.js yang dapat digunakan

npm install -g browserify
browserify three-bmfont-text.js -o three-bmfont-text-bundle.js

4. Shader SDF

Sesuaikan penggeser afwidth dan threshold di vr.with.in/archive/text-sdf-bitmap/ untuk melihat pengaruh shader bidang jarak jauh yang ditandai.

5. Penggunaan

Untuk memudahkan, saya membuat Class wrapper TextBitmap untuk teks tiga-bmfont-browser.

Cara kerja text-sdf-bitmap
Penerapan text-sdf-bitmap
<script src="three-bmfont-text-bundle.js"></script>
<script src="sdf-shader.js"></script>
<script src="text-bitmap.js"></script>

Buat permintaan XHR untuk file font .json dan buat objek teks di bagian telepon balik:

var bmtext = new TextBitmap({ options });

Untuk mengubah teks:

bmtext.text = 'The quick brown fox jumps over the lazy dog.';

scene.add( bmtext.group );
hitBoxes.push( bmtext.hitBox );

.png font bitmap dimuat dengan THREE.TextureLoader di text-bitmap.js

TextBitmap juga menyertakan hitbox yang tidak terlihat untuk interaksi raycast tiga.js melalui {i>mouse<i}, kamera, atau pengontrol gerakan yang dilacak dengan tangan seperti Oculus Touch atau pengontrol Vive. Ukuran hitbox diperbarui secara otomatis saat Anda mengubah teks lainnya.

Bmtext.group ditambahkan ke tampilan Three.js. Jika Anda perlu mengakses akun turunan / Object3D, grafik scene untuk teks akan terlihat seperti ini:

Diagram sistem file

6. Membatalkan json dan mengubah xoffset

Gif dalam teks

Jika kerning Anda tidak berfungsi, Anda mungkin perlu mengedit xoffsets di json. Menempel buka json ke Jsbeautifier.org untuk mendapatkan yang tidak diminifikasi dari {i>file<i}.

Pada dasarnya, {i>xoffset<i} adalah kerning global untuk satu karakter. Kerning adalah untuk dua karakter tertentu yang muncul berdampingan. Nilai default di kolom kerning array tidak benar-benar membuat perbedaan, dan akan terlalu membosankan untuk edit, sehingga Anda dapat mengosongkan array tersebut untuk mengurangi ukuran file json. Selanjutnya edit xoffset untuk kerning.

Pertama, Anda harus mencari tahu karakter mana yang digunakan dengan ID karakter dalam JSON. Di three-bmfont-text-bundle.js, masukkan console.log setelah baris 240:

    var id = text.charCodeAt(i)
    // console.log(id);

Kemudian ketik ke isian teks {i>dat.gui <i}di https://vr.with.in/archive/text-sdf-bitmap/ dan periksa konsol untuk menemukan ID karakter yang sesuai.

Misalnya, dalam font bitmap, "j" selalu terlalu jauh ke kanan. Ini ID karakter adalah 106. Jadi temukan "id": 106 dalam json dan ubah xoffset-nya dari -1 menjadi -10.

7. Tata Letak

Jika Anda memiliki beberapa blok teks dan ingin teksnya mengalir dari atas ke bawah seperti di HTML, semuanya harus diposisikan secara manual, mirip dengan pemosisian absolut setiap elemen dom dengan CSS. Dapatkah Anda bayangkan melakukan ini dalam CSS?

    * { position: absolute; }

Seperti itulah tata letak teks dalam 3D. Dalam tampilan detail: judul, penulis, deskripsi, dan durasi masing-masing adalah objek TextBitmap baru dengan gaya, warna, skala, dll.:

Tata letak 3D
author.group.position.y = title.group.position.y - title.height - padding;
description.group.position.y = author.group.position.y - author.height - padding;
duration.group.position.y = description.group.position.y - description.height - padding;

Hal ini mengasumsikan bahwa asal lokal setiap grup TextBitmap secara vertikal sejajar dengan bagian atas mesh TextBitmap (lihat bagian tengah text-bitmap.js ). Jika Anda mengubah teks untuk salah satu objek tersebut di lain waktu, dan tingginya perubahan objek tersebut, Anda juga perlu menghitung ulang posisi tersebut. Di sini, hanya posisi y dari teks yang dimodifikasi, tetapi satu kesempatan untuk bekerja di 3D adalah kita bisa mendorong dan menarik teks dalam arah z, serta memutar di sekitar sumbu x, y, dan z.

Kesimpulan

Teks dan tata letak di WebVR masih jauh untuk digunakan semudah dan banyak digunakan sebagai HTML dan CSS. Tetapi ada solusi yang bermanfaat dan Anda dapat melakukan lebih banyak lagi di WebVR daripada yang dapat Anda lakukan dengan laman web HTML tradisional. WebVR ada saat ini. Mungkin akan ada alat yang lebih baik besok. Sampai saat itu, cobalah dan eksperimen. Mengembangkan tanpa kerangka kerja yang ada di mana-mana akan menghasilkan pengalaman yang lebih unik proyek, dan itu sangat menarik.