Hiển thị văn bản trong WebVR

Trong phần Chi tiết

Xem trang web

Trong (https://with.in/) là một nền tảng để kể chuyện trong thực tế ảo. Vì vậy, khi đội ngũ của tôi biết đến WebVR vào năm 2015, chúng tôi đã ngay lập tức quan tâm đến tiềm năng của nó. Hiện nay, mối quan tâm đó thể hiện trong một miền con duy nhất trên nền tảng web của chúng tôi, https://vr.with.in/. Bất kỳ ai có trình duyệt hỗ trợ thực tế ảo (VR) có thể truy cập trang web, nhấp vào nút và đeo tai nghe để đắm chìm trong danh mục phim thực tế ảo của chúng tôi.

Hiện nay, bao gồm nhưng không giới hạn ở Chrome trên Daydream View. Để biết thông tin về thiết bị của bạn và màn hình hiển thị đeo đầu, hãy truy cập vào https://webvr.info/.

Giống như các môi trường kết xuất thực tế ảo khác, web chủ yếu dựa vào việc thể hiện cảnh ba chiều. Cảnh này có một máy ảnh, góc nhìn của bạn và số lượng đối tượng bất kỳ. Để giúp quản lý cảnh, máy ảnh và đối tượng này, chúng tôi sử dụng một thư viện có tên là Three.js. Thư viện này tận dụng phần tử <canvas> để gửi nội dung kết xuất vào GPU của máy tính. Có nhiều tiện ích bổ sung Three.js hữu ích giúp bạn xem được cảnh trong WebVR. Hai tuỳ chọn chính là THREE.VREffect để tạo khung nhìn cho mỗi mắt và THREE.VRControls để dịch phối cảnh (ví dụ: góc xoay và vị trí của màn hình hiển thị đầu) một cách thuyết phục vào cảnh của bạn. Có nhiều ví dụ về cách triển khai việc này. Hãy xem các ví dụ về thử nghiệm 3.js WebVR để biết các cách bắt đầu.

Khi tìm hiểu sâu hơn về WebVR, chúng tôi đã gặp phải một vấn đề. Nếu chúng ta xem xét nội dung của web, thì văn bản là một phần không thể thiếu trong đó. Mặc dù phần lớn nội dung của chúng tôi là dựa trên video, nhưng nếu bạn truy cập văn bản Trong trang web, văn bản sẽ bao quanh nội dung; giao diện người dùng và thông tin bổ sung về một bộ phim hoặc các bộ phim liên quan đều được xây dựng bằng văn bản. Hơn nữa, tất cả văn bản này đều được tạo trong DOM. Dữ liệu khám phá WebVR và https://vr.with.in/ của chúng tôi đều có trong <canvas>.

Văn bản được sử dụng trong WebVR Văn bản được sử dụng trong WebVR
Văn bản dùng trong WebVR cho vr.with.in

Tôi có những Tuỳ chọn nào?

Thật may là chúng tôi đang tiến hành xử lý để việc này có thể trở thành hiện thực. Trên thực tế, trong nghiên cứu của mình, chúng tôi đã tìm thấy một số cách hiệu quả để hiển thị văn bản trong môi trường ba chiều trên phần tử <canvas>. Dưới đây là ma trận về một số tiêu chí mà chúng tôi đã tìm thấy với các ưu và nhược điểm của từng loại:

Độc lập về độ phân giải Tính năng về kiểu chữ Hiệu suất Dễ dàng triển khai
Văn bản trên canvas 2D
Văn bản vectơ được cố định
Văn bản 3D được ép đùn
Văn bản bitmap của trường khoảng cách đã ký

Quyết định của chúng tôi: Phông chữ Bitmap SDF

Canvas 2D với ctx.fillText() có thể xuống dòng tự động, giãn cách chữ cái và chiều cao dòng, nhưng phần tràn bị cắt và văn bản sẽ bị mờ nếu bạn phóng to thực sự xa. Bạn có thể tăng kích thước của hoạ tiết canvas, nhưng nếu hoạ tiết quá lớn thì hiệu suất hoặc kích thước hoạ tiết có thể sẽ đạt đến giới hạn trên.

Văn bản 3D ép đùn về cơ bản giống như văn bản vectơ hình tam giác, nhưng có chiều sâu và có thể là một góc xiên nên văn bản này có hình dạng ít nhất gấp đôi. Một trong hai cách này có thể hoạt động với số lượng nhỏ cho tiêu đề hoặc biểu trưng, nhưng sẽ không hoạt động hiệu quả với số lượng lớn văn bản và cả hai tính năng này đều không có tính năng đánh máy.

Quy trình chuyển phông chữ sang SDF
Quy trình xử lý bitmap phông chữ cho SDF

Phông chữ Bitmap sử dụng một phần tư (2 tam giác) cho mỗi ký tự nên sử dụng ít hình học hơn và hoạt động tốt hơn vectơ tam giác. Các đối tượng này vẫn dựa trên đường quét vì sử dụng một sprite bản đồ hoạ tiết, nhưng với chương trình đổ bóng SDF, về cơ bản, các đối tượng này không phụ thuộc vào độ phân giải nên trông đẹp hơn hoạ tiết canvas 2D. Văn bản 3 bmfont của Matt DesLauriers cũng có các tính năng phông chữ đáng tin cậy để xuống dòng tự động, giãn cách chữ, chiều cao dòng và căn chỉnh. Mục hiển thị tràn không bị cắt. Kích thước phông chữ được kiểm soát thông qua tỷ lệ. Chúng tôi chọn lộ trình này vì nó mang lại cho chúng tôi các lựa chọn tốt nhất về thiết kế mà vẫn duy trì hiệu suất cao. Thật không may, việc triển khai không dễ dàng như vậy, vì vậy chúng tôi sẽ hướng dẫn các bước với hy vọng có thể trợ giúp các nhà phát triển khác làm việc trong WebVR.

1. Tạo phông chữ bitmap (.png + .fnt)

Giao diện Hiero
Giao diện Hiero
Dữ liệu đầu ra Hiero (tệp PNG Bitmap và .fnt) Dữ liệu đầu ra Hiero (tệp PNG Bitmap và .fnt)
Đầu ra Hiero (tệp PNG và .fnt)

Hiero là công cụ đóng gói phông chữ bitmap chạy cùng Java. Tài liệu Hiero không thực sự giải thích cách chạy mà không trải qua một quy trình xây dựng phức tạp. Trước tiên, hãy cài đặt Java nếu bạn chưa cài đặt. Sau đó, nếu thao tác nhấp đúp vào runnable-hiero.jar không mở Hiero, hãy thử chạy bằng lệnh sau trong bảng điều khiển:

java -jar runnable-hiero.jar

Khi Hiero đang chạy, hãy mở phông chữ .ttf hoặc .otf trên màn hình, nhập bất kỳ ký tự bổ sung nào bạn muốn đưa vào, thay đổi kết xuất thành Java để bật hiệu ứng, tăng kích thước để các ký tự lấp đầy toàn bộ hình vuông trong bộ nhớ đệm ký tự, thêm hiệu ứng trường khoảng cách, điều chỉnh tỷ lệ và độ trải của trường khoảng cách. Giá trị tỷ lệ giống như một độ phân giải. Giá trị càng cao thì bản xem trước càng ít bị mờ, nhưng Hiero sẽ càng mất nhiều thời gian để hiển thị bản xem trước. Sau đó, lưu phông chữ bitmap. Công cụ này tạo phông chữ bitmap bao gồm hình ảnh .png và tệp mô tả phông chữ .fnt của AngelCode.

2. Chuyển đổi AngelCode thành JSON

Bây giờ, phông chữ bitmap đã được tạo, chúng ta phải tải phông chữ đó vào ứng dụng JavaScript thông qua gói load-bmfont npm của Matt DesLauriers.

Chúng ta có thể trình duyệt load-bmfont và sử dụng nó trên giao diện người dùng, nhưng thay vào đó, chúng ta sẽ chạy load-bmfont.js bằng Nút để chuyển đổi và lưu AngelCode .fnt của Hiero vào tệp.json:

npm install
node load-bmfont.js
Ví dụ về tệp JSON đầu ra
Ví dụ về JSON đầu ra

Giờ đây, chúng ta có thể bỏ qua load-bmfont và chỉ cần thực hiện yêu cầu XHR (XMLHttpRequest) trên tệp phông chữ .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. Trình duyệt văn bản 3-bmfont

Sau khi tải phông chữ xong, văn bản 3 bmfont của Matt sẽ xử lý phần còn lại. Vì không dùng Node cho ứng dụng của riêng mình, nên chúng ta sẽ chuyển sang trình duyệt ba-bmfont-text.js thành một three-bmfont-text-bundle.js có thể sử dụng được

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

4. Chương trình đổ bóng SDF

Điều chỉnh thanh trượt afwidththreshold trên vr.with.in/archive/text-sdf-bitmap/ để xem tác động của chương trình đổ bóng trường khoảng cách đã ký.

5. Cách sử dụng

Để thuận tiện, tôi đã tạo một lớp trình bao bọc TextBitmap cho văn bản 3-bmfont-text được trình duyệt.

Văn bản-sdf-bitmap trong thực tế
Hoạt động của Text-sdf-bitmap trong thực tế
<script src="three-bmfont-text-bundle.js"></script>
<script src="sdf-shader.js"></script>
<script src="text-bitmap.js"></script>

Tạo một yêu cầu XHR cho tệp phông chữ .json và tạo một đối tượng văn bản trong lệnh gọi lại:

var bmtext = new TextBitmap({ options });

Cách thay đổi văn bản:

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

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

Tệp .png của phông chữ bitmap được tải bằng ba.TextureLoader trong text-bitmap.js

TextBitmap cũng bao gồm một hộp truy cập vô hình cho các hoạt động tương tác raycast 3.js thông qua chuột, máy ảnh hoặc bộ điều khiển chuyển động được theo dõi bằng tay như Oculus Touch hoặc bộ điều khiển Vive. Kích thước của hộp truy cập tự động cập nhật khi bạn thay đổi tuỳ chọn văn bản.

Bmtext.group được thêm vào cảnh third.js. Nếu bạn cần truy cập vào phần tử con/Object3D, biểu đồ cảnh cho văn bản sẽ có dạng như sau:

Sơ đồ hệ thống tệp

6. Hợp nhất tệp json và sửa đổi phần chênh lệch

Trong ảnh GIF văn bản

Nếu khoảng cách giữa các thành phần có thể không được loại bỏ, bạn có thể cần phải chỉnh sửa các xoffset trong tệp json. Dán tệp json vào Jsbeautifier.org để có phiên bản tệp chưa rút gọn.

Xoffset về cơ bản là khoảng cách chung cho một nhân vật. Kerning là tính năng dành cho 2 ký tự cụ thể xuất hiện cạnh nhau. Các giá trị mặc định trong mảng mã nguồn không thực sự tạo ra sự khác biệt và việc chỉnh sửa sẽ quá tẻ nhạt. Vì vậy, bạn có thể để trống mảng đó để giảm kích thước tệp của json. Sau đó, hãy chỉnh sửa các xoffsets để nhận diện.

Trước tiên, bạn cần tìm ra ký tự nào đi với mã nhận dạng ký tự nào trong tệp json. Trong three-bmfont-text-bundle.js, hãy chèn console.log sau dòng 240:

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

Sau đó, nhập vào trường văn bản data.gui trên https://vr.with.in/archive/text-sdf-bitmap/ rồi kiểm tra bảng điều khiển để tìm mã nhận dạng tương ứng của một ký tự.

Ví dụ: trong phông chữ bitmap của chúng ta, "j" luôn ở quá xa bên phải. Mã ký tự của thuộc tính này là 106. Vì vậy, hãy tìm "id": 106 trong tệp json và thay đổi giá trị xoffset từ -1 thành -10.

7. Bố cục

Nếu bạn có nhiều khối văn bản và muốn văn bản di chuyển từ trên xuống dưới như HTML, mọi thứ phải được định vị theo cách thủ công, tương tự như việc tự định vị tuyệt đối mọi phần tử dom với CSS. Bạn có thể hình dung việc này trong CSS không?

    * { position: absolute; }

Đó là giao diện của bố cục văn bản trong 3D. Trong chế độ xem chi tiết: tiêu đề, tác giả, nội dung mô tả và thời lượng là một đối tượng TextBitmap mới có kiểu, màu sắc, tỷ lệ riêng, v.v.:

bố cục 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;

Điều này giả định rằng nguồn gốc cục bộ của mỗi nhóm TextBitmap được căn chỉnh theo chiều dọc với phần trên cùng của lưới TextBitmap (xem phần căn giữa trong nội dung cập nhật text-bitmap.js). Nếu sau này bạn thay đổi văn bản cho bất kỳ đối tượng nào trong số đó và chiều cao của đối tượng đó thay đổi, thì bạn cũng sẽ phải tính toán lại các vị trí đó. Ở đây, chỉ có vị trí y của văn bản được sửa đổi, nhưng có một cơ hội để làm việc trong 3D là chúng ta có thể đẩy và kéo văn bản theo hướng z, cũng như xoay xung quanh các trục x, y và z.

Kết luận

Văn bản và bố cục trong WebVR còn rất dài nữa trước khi trở nên dễ sử dụng và được sử dụng rộng rãi như HTML và CSS. Nhưng các giải pháp hiệu quả đã tồn tại và bạn có thể làm được nhiều việc hơn trong WebVR so với với trang web HTML truyền thống. WebVR đã tồn tại đến hôm nay. Có thể sẽ có các công cụ tốt hơn vào ngày mai. Cho đến lúc đó, hãy dùng thử và thử nghiệm. Việc phát triển mà không cần một bộ khung phổ biến sẽ dẫn đến nhiều dự án độc đáo hơn. Điều này thật tuyệt vời.