Afficher du texte dans WebVR

Dans les détails

Consulter le site

Au sein de (https://with.in/) est une plate-forme de storytelling en réalité virtuelle. Quand l'équipe a entendu parler de WebVR, l'année 2015, nous avons immédiatement été intéressés par son potentiel. Aujourd'hui, cet intérêt se manifeste dans un sous-domaine unique de notre plate-forme Web, https://vr.with.in/. Toute personne disposant d'un navigateur compatible avec la réalité virtuelle peut : accédez au site, cliquez sur un bouton et mettez un casque pour vous immerger dans notre de films en réalité virtuelle.

Aujourd'hui, cela inclut, mais sans s'y limiter, Chrome sur Daydream View. Pour des informations sur votre appareil et votre visiocasque, consultez https://webvr.info/.

Comme d'autres environnements de rendu dédiés à la réalité virtuelle, le Web repose principalement sur la représentation en trois dimensions d'une scène. Ce comporte une caméra, votre perspective et un nombre illimité d'objets. Pour vous aider à gérer cette scène, cette caméra et ces objets, nous utilisons une bibliothèque appelée Three.js qui utilise l'élément <canvas> pour générer sur le GPU de votre ordinateur. Il existe de nombreux modules complémentaires Three.js utiles pour rendre la scène visible dans WebVR. Les deux principaux sont THREE.VREffect pour créer une fenêtre d'affichage pour chaque œil THREE.VRControls pour traduire la perspective (par exemple, la rotation et la position du visé) de façon convaincante dans votre environnement. Il existe de nombreux exemples de comment procéder. Consultez le Exemples de WebVR Three.js pour vous lancer.

Lorsque nous avons commencé à explorer WebVR, nous avons rencontré un problème. Si nous regardons au contenu du Web, le texte fait partie intégrante. Bien que la majorité de notre contenu est basé sur des vidéos. Le texte dans le site encadre le contenu. L'interface utilisateur et les informations supplémentaires sur un film ou un film associé construit avec du texte. De plus, tout ce texte est créé dans le DOM. Notre Les explorations WebVR et https://vr.with.in/ sont toutes <canvas>

<ph type="x-smartling-placeholder">
</ph> Texte utilisé dans WebVR Texte utilisé dans WebVR <ph type="x-smartling-placeholder">
</ph> Texte utilisé dans WebVR pour vr.with.in

Quelles sont mes options ?

Heureusement, des efforts sont en cours pour que tout cela soit possible. En fait, lors de nos recherches, nous avons trouvé un certain nombre de méthodes efficaces pour afficher du texte dans un format sur un élément <canvas>. Vous trouverez ci-dessous une matrice présentant quelques-uns avec leurs avantages et leurs inconvénients:

Indépendant de la résolution Caractéristiques typographiques Performances Facilité d'implémentation
Texte du canevas 2D Oui Oui Oui
Texte vectoriel triangulé Oui Oui
Texte 3D extrudé Oui
Texte bitmap du champ de distance signée Oui Oui Oui

Notre décision: Police de bitmap SDF

Le canevas 2D avec ctx.fillText() permet le retour automatique à la ligne, l'espacement des lettres et le trait mais le dépassement est tronqué et le texte sera flou si vous faites un zoom avant à distance. Vous pouvez augmenter la taille de la texture du canevas, mais vous risquez d'atteindre une la taille ou les performances d'une texture peuvent en pâtir si elle est trop grande.

Le texte 3D extrudé est essentiellement identique au texte vectoriel triangulé, mais avec de profondeur et éventuellement un biseau, de sorte qu'il présente au moins deux fois plus de géométrie. Soit ces éléments peuvent fonctionner à petite dose pour les titres ou les logos, mais ils ne sont pas aussi efficaces pour de grandes quantités de texte, et aucune des deux n'a de caractéristiques typographiques.

<ph type="x-smartling-placeholder">
</ph> Workflow bitmap de la police vers des fichiers SDF
Workflow de bitmaps police vers SDF
.

Les polices bitmap utilisent un quad (deux triangles) par caractère. Elles en utilisent donc moins sa géométrie et ses performances vecteurs triangulés. Ils sont toujours basés sur des trames, car ils utilisent un lutin de carte de texture, mais avec un fichier de données structurées Ils sont indépendants de la résolution et offrent donc un meilleur rendu qu'un nuanceur la texture du canevas. Matt DesLauriers' trois-bmfont-text inclut également des fonctionnalités typographiques fiables pour le retour automatique à la ligne, l'espacement des lettres, la hauteur des lignes et l'alignement. Le débordement n'est pas tronqué. Police est contrôlée par l'échelle. Nous avons choisi cette voie, car elle nous donnait les meilleures options de conception tout en restant performant. Malheureusement, ce n'était pas aussi facile à mettre en œuvre. Nous suivrons donc les étapes dans le but d'aider les autres développeurs travaillant dans WebVR.

1. Générer une police bitmap (.png + .fnt)

<ph type="x-smartling-placeholder">
</ph> Interface Hiero
Interface Hiero
. <ph type="x-smartling-placeholder">
</ph> Sortie Hiero (fichier bitmap PNG et .fnt) Sortie Hiero (fichier bitmap PNG et .fnt)
Sortie Hiero (fichier bitmap PNG et .fnt)
.

Hiero est un pack de polices bitmap qui s'exécute avec Java. La documentation de Hiero n'explique pas vraiment comment sans passer par un processus de compilation compliqué. Tout d'abord, installez Java si ce n'est pas déjà fait. Ensuite, si double-cliquez sur le fichier runnable-hiero.jar, ouvrez Hiero, exécutez-le à l'aide de la commande suivante dans la console:

java -jar runnable-hiero.jar

Une fois que Hiero est en cours d'exécution, ouvrez une police .ttf ou .otf pour ordinateur de bureau, saisissez les caractères à inclure, remplacez le rendu par Java pour activer les effets, augmenter la taille pour que vos caractères occupent tout le carré du cache des glyphes, ajouter un effet de champ de distance, ajuster l'échelle et l'étendue du champ de distance. La la valeur d'échelle est comme une résolution. Plus il est élevé, moins il est flou, mais plus il faudra de temps à Hiero pour afficher l'aperçu. Ensuite, enregistrez votre et la police bitmap. Il génère une police bitmap composée d'une image .png et d'une Fichier de description de police .fnt AngelCode.

2. Convertir AngelCode en JSON

Maintenant que la police bitmap a été générée, nous devons la charger dans notre avec l'application JavaScript Matt DesLauriers package npm load-bmfont.

Nous pourrions naviguer sur load-bmfont et l'utiliser sur le frontal, mais au lieu de cela, va s'exécuter load-bmfont.js avec Nœud pour convertir et enregistrer le fichier .fnt de Hiero's AngelCode dans un Fichier.json:

npm install
node load-bmfont.js
<ph type="x-smartling-placeholder">
</ph> Exemple de sortie JSON
Exemple de sortie JSON

Nous pouvons maintenant contourner load-bmfont et exécuter simplement une requête XHR (XMLHttpRequest) sur le .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. Browserify trois-bmfont-text

Une fois la police chargée, le texte "3-bmfont-text" de Matt se charge reste. Puisque nous n'utilisons pas Node pour notre propre application, browserify three-bmfont-text.js dans un fichier three-bmfont-text-bundle.js utilisable

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

4. Nuanceur de fichiers SDF

Ajustez les curseurs afwidth et threshold. vr.with.in/archive/text-sdf-bitmap/ pour voir l'effet du nuanceur de champs de distance signée.

5. Utilisation

Pour plus de commodité, j'ai créé Classe wrapper TextBitmap pour le texte "3-bmfont-text" dans le navigateur.

<ph type="x-smartling-placeholder">
</ph> Text-sdf-bitmap en action
Text-sdf-bitmap en action
.
<script src="three-bmfont-text-bundle.js"></script>
<script src="sdf-shader.js"></script>
<script src="text-bitmap.js"></script>

Créez une requête XHR pour le fichier de polices .json et créez un objet texte dans le fichier rappel:

var bmtext = new TextBitmap({ options });

Pour modifier le texte:

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

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

Le fichier .png de la police bitmap est chargé avec THREE.TextureLoader dans text-bitmap.js.

TextBitmap inclut également un masque de collision invisible pour l'interaction Raycast 3.js à l'aide d'une souris, d'un appareil photo ou de contrôleurs de mouvement avec suivi de la main comme Oculus Touch ou les manettes Vive. La taille du masque de collision est mise à jour automatiquement lorsque vous modifiez le texte. options.

Bmtext.group est ajouté à la scène three.js. Si vous devez accéder aux éléments enfants / Object3D, le graphique de scène du texte se présente comme suit:

Schéma du système de fichiers

6. Réduction de la taille des fichiers JSON et modification des décalages X

GIF du texte inclus

Si votre crénage n'est pas visible, vous devrez peut-être modifier les décalages X dans le fichier JSON. Coller le fichier JSON dans Jsbeautifier.org pour obtenir version réduite du fichier.

Le décalage X est essentiellement un crénage global pour un caractère. Le crénage est pour deux des caractères spécifiques qui s'affichent l'un à côté de l'autre. Les valeurs par défaut de la section de crénage ne font pas de différence et il serait trop fastidieux modifier. Vous pouvez donc vider ce tableau pour réduire la taille du fichier JSON. Ensuite, modifier les décalages X pour le crénage.

Vous devez d'abord déterminer quels caractères sont associés à quel ID de caractère dans JSON. Dans three-bmfont-text-bundle.js, insérez console.log après la ligne 240:

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

Tapez ensuite dans le champ de texte dat.gui sur https://vr.with.in/archive/text-sdf-bitmap/ et consulter la console pour trouver l'ID correspondant à un caractère.

Par exemple, dans notre police bitmap, "j" est systématiquement trop éloignée vers la droite. Son char ID est 106. Recherchez "id": 106 dans le fichier JSON et remplacez la valeur "-1" par "xoffset" à -10.

7. Mise en page

Si vous avez plusieurs blocs de texte et que vous souhaitez qu'il s'écoule de haut en bas, comme HTML : tous les éléments doivent être positionnés manuellement, comme pour le positionnement absolu. vous-même chaque élément dom avec CSS. Pouvez-vous imaginer faire cela en CSS ?

    * { position: absolute; }

Voilà à quoi ressemble la mise en page du texte en 3D. Dans la vue détaillée: titre, auteur, la description et la durée sont chacun un nouvel objet TextBitmap ayant leurs propres styles, couleurs, échelle, etc.:

Mise en page 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;

Cela suppose que l'origine locale de chaque groupe TextBitmap est verticalement aligné sur la partie supérieure du maillage TextBitmap (voir le centrage dans text-bitmap.js mise à jour). Si, par la suite, vous modifiez le texte de l'un de ces objets, ainsi que la hauteur de ces modifications d'objets, vous devez également recalculer leur position. Ici, seule la position Y du texte est modifiée, mais vous pouvez travailler En 3D, on peut pousser et extraire le texte dans la direction Z, et le faire pivoter. autour des axes x, y et z.

Conclusion

Avec WebVR, le texte et la mise en page sont encore loin d'être aussi simples largement utilisé comme HTML et CSS. Mais des solutions fonctionnelles existent et vous pouvez faire beaucoup plus dans WebVR qu'avec une page Web HTML traditionnelle. WebVR existe aujourd'hui. Il y aura probablement de meilleurs outils demain. En attendant, essayez-le et test. Le développement sans cadre omniprésent ouvre la voie à des projets, et c’est passionnant.