Un examen approfondi des résultats des tests de collision WebXR et du traitement du lancer de rayon, essentiels pour créer des expériences de réalité augmentée et virtuelle interactives et intuitives sur le Web.
Résultat du test de collision WebXR : traitement des résultats de lancer de rayon pour des expériences immersives
L’API WebXR Device offre des possibilités passionnantes pour créer des expériences immersives de réalité augmentée (RA) et de réalité virtuelle (RV) directement dans le navigateur. L’un des aspects fondamentaux de la création d’applications WebXR interactives est de comprendre et d’utiliser efficacement les résultats des tests de collision. Cet article de blog fournit un guide complet sur le traitement des résultats des tests de collision obtenus par le biais du lancer de rayon, vous permettant de créer des interactions utilisateur intuitives et engageantes dans vos scènes WebXR.
Qu’est-ce que le lancer de rayon et pourquoi est-ce important dans WebXR ?
Le lancer de rayon est une technique utilisée pour déterminer si un rayon, provenant d’un point et d’une direction spécifiques, croise des objets dans une scène 3D. Dans WebXR, le lancer de rayon est généralement utilisé pour simuler le regard de l’utilisateur ou la trajectoire d’un objet virtuel. Lorsque le rayon croise une surface du monde réel (en RA) ou un objet virtuel (en RV), un résultat de test de collision est généré.
Les résultats des tests de collision sont essentiels pour plusieurs raisons :
- Placement d’objets virtuels : En RA, les tests de collision vous permettent de placer avec précision des objets virtuels sur des surfaces du monde réel, telles que des tables, des sols ou des murs.
- Interaction de l’utilisateur : En suivant l’endroit où l’utilisateur regarde ou pointe, les tests de collision permettent d’interagir avec des objets virtuels, tels que la sélection, la manipulation ou l’activation de ces derniers.
- Navigation : Dans les environnements RV, les tests de collision peuvent être utilisés pour implémenter des systèmes de navigation, permettant aux utilisateurs de se téléporter ou de se déplacer dans la scène en pointant vers des emplacements spécifiques.
- Détection de collision : Les tests de collision peuvent être utilisés pour la détection de collision de base, en déterminant quand un objet virtuel entre en collision avec un autre objet ou le monde réel.
Comprendre l’API de test de collision WebXR
L’API de test de collision WebXR fournit les outils nécessaires pour effectuer le lancer de rayon et obtenir les résultats des tests de collision. Voici une description des principaux concepts et fonctions :
XRRay
Un XRRay représente un rayon dans l’espace 3D. Il est défini par un point d’origine et un vecteur de direction. Vous pouvez créer un XRRay à l’aide de la méthode XRFrame.getPose(), qui renvoie la pose d’une source d’entrée suivie (par exemple, la tête de l’utilisateur, un contrôleur manuel). À partir de la pose, vous pouvez dériver l’origine et la direction du rayon.
XRHitTestSource
Un XRHitTestSource représente une source de résultats de test de collision. Vous créez une source de test de collision à l’aide de la méthode XRSession.requestHitTestSource() ou XRSession.requestHitTestSourceForTransientInput(). La première méthode est généralement utilisée pour les tests de collision continus basés sur une source persistante, telle que la position de la tête de l’utilisateur, tandis que la seconde est destinée aux événements d’entrée transitoires, tels que les pressions de bouton ou les gestes.
XRHitTestResult
Un XRHitTestResult représente un point d’intersection unique entre le rayon et une surface. Il contient des informations sur l’intersection, telles que la distance entre l’origine du rayon et le point de collision, ainsi que la pose du point de collision dans l’espace de référence de la scène.
XRHitTestResult.getPose()
Cette méthode renvoie le XRPose du point de collision. La pose contient la position et l’orientation du point de collision, qui peuvent être utilisées pour placer des objets virtuels ou effectuer d’autres transformations.
Traitement des résultats des tests de collision : un guide étape par étape
Passons en revue le processus d’obtention et de traitement des résultats des tests de collision dans une application WebXR. Cet exemple suppose que vous utilisez une bibliothèque de rendu comme three.js ou Babylon.js.
1. Demande d’une source de test de collision
Tout d’abord, vous devez demander une source de test de collision à partir de XRSession. Cela se fait généralement après le démarrage de la session. Vous devrez spécifier le système de coordonnées dans lequel vous souhaitez que les résultats des tests de collision soient renvoyés. Par exemple :
let xrHitTestSource = null;
async function createHitTestSource(xrSession) {
try {
xrHitTestSource = await xrSession.requestHitTestSource({
space: xrSession.viewerSpace // Or xrSession.local
});
} catch (error) {
console.error("Failed to create hit test source: ", error);
}
}
// Call this function after the XR session has started
// createHitTestSource(xrSession);
Explication :
xrSession.requestHitTestSource() : cette fonction demande une source de test de collision à partir de la session XR.{ space: xrSession.viewerSpace } : cela spécifie le système de coordonnées dans lequel les résultats des tests de collision seront renvoyés.viewerSpaceest relatif à la position du spectateur, tandis quelocalest relatif à l’origine XR. Vous pouvez également utiliserlocalFloorpour effectuer un suivi par rapport au sol.- Gestion des erreurs : le bloc
try...catchgarantit que les erreurs survenant lors de la création de la source de test de collision sont détectées et consignées.
2. Effectuer le test de collision dans la boucle d’animation
Dans votre boucle d’animation (la fonction qui restitue chaque image), vous devrez effectuer le test de collision à l’aide de la méthode XRFrame.getHitTestResults(). Cette méthode renvoie un tableau d’objets XRHitTestResult, représentant toutes les intersections trouvées dans la scène.
function onXRFrame(time, frame) {
const session = frame.session;
session.requestAnimationFrame(onXRFrame);
const pose = frame.getViewerPose(xrSession.referenceSpace);
if (pose) {
if (xrHitTestSource) {
const hitTestResults = frame.getHitTestResults(xrHitTestSource);
if (hitTestResults.length > 0) {
processHitTestResults(hitTestResults);
}
}
}
renderer.render(scene, camera);
}
Explication :
frame.getViewerPose(xrSession.referenceSpace) : obtient la pose du spectateur (casque). Ceci est nécessaire pour savoir où se trouve le spectateur et où il regarde.frame.getHitTestResults(xrHitTestSource) : effectue le test de collision à l’aide de la source de test de collision précédemment créée.hitTestResults.length > 0 : vérifie si des intersections ont été trouvées.
3. Traitement des résultats des tests de collision
La fonction processHitTestResults() est l’endroit où vous traiterez les résultats du test de collision. Cela implique généralement de mettre à jour la position et l’orientation d’un objet virtuel en fonction de la pose du point de collision.
function processHitTestResults(hitTestResults) {
const hit = hitTestResults[0]; // Get the first hit result
const hitPose = hit.getPose(xrSession.referenceSpace);
if (hitPose) {
// Update the position and orientation of a virtual object
virtualObject.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z);
virtualObject.quaternion.set(hitPose.transform.orientation.x, hitPose.transform.orientation.y, hitPose.transform.orientation.z, hitPose.transform.orientation.w);
// Show visual feedback (e.g., a circle) at the hit point
hitMarker.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z);
hitMarker.quaternion.set(hitPose.transform.orientation.x, hitPose.transform.orientation.y, hitPose.transform.orientation.z, hitPose.transform.orientation.w);
hitMarker.visible = true;
} else {
hitMarker.visible = false;
}
}
Explication :
hitTestResults[0] : récupère le premier résultat du test de collision. Si plusieurs intersections sont possibles, vous devrez peut-être parcourir l’ensemble du tableau et choisir le résultat le plus approprié en fonction de la logique de votre application.hit.getPose(xrSession.referenceSpace) : obtient la pose du point de collision dans l’espace de référence spécifié.virtualObject.position.set(...)etvirtualObject.quaternion.set(...) : mettez à jour la position et la rotation (quaternion) d’un objet virtuel (par exemple, unMeshthree.js) pour qu’elles correspondent à la pose du point de collision.- Rétroaction visuelle : l’exemple comprend également du code permettant d’afficher une rétroaction visuelle au niveau du point de collision, tel qu’un cercle ou un marqueur simple, afin d’aider l’utilisateur à comprendre l’endroit où il interagit avec la scène.
Techniques avancées de test de collision
Au-delà de l’exemple de base ci-dessus, vous pouvez utiliser plusieurs techniques avancées pour améliorer vos implémentations de test de collision :
Test de collision avec entrée transitoire
Pour les interactions déclenchées par une entrée transitoire, telle que les pressions de bouton ou les gestes de la main, vous pouvez utiliser la méthode XRSession.requestHitTestSourceForTransientInput(). Cette méthode crée une source de test de collision spécifique à un événement d’entrée unique. Ceci est utile pour éviter les interactions involontaires basées sur des tests de collision continus.
async function handleSelect(event) {
try {
const frame = event.frame;
const inputSource = event.inputSource;
const hitTestResults = await frame.getHitTestResultsForTransientInput(inputSource, {
profile: 'generic-touchscreen', // Or the appropriate input profile
space: xrSession.viewerSpace
});
if (hitTestResults.length > 0) {
processHitTestResults(hitTestResults);
}
} catch (error) {
console.error("Error during transient hit test: ", error);
}
}
// Attach this function to your input select event listener
// xrSession.addEventListener('select', handleSelect);
Filtrage des résultats des tests de collision
Dans certains cas, vous souhaiterez peut-être filtrer les résultats des tests de collision en fonction de critères spécifiques, tels que la distance par rapport à l’origine du rayon ou le type de surface qui a été croisée. Vous pouvez y parvenir en filtrant manuellement le tableau XRHitTestResult après l’avoir obtenu.
function processHitTestResults(hitTestResults) {
const filteredResults = hitTestResults.filter(result => {
const hitPose = result.getPose(xrSession.referenceSpace);
if (!hitPose) return false; // Skip if no pose
const distance = Math.sqrt(
Math.pow(hitPose.transform.position.x - camera.position.x, 2) +
Math.pow(hitPose.transform.position.y - camera.position.y, 2) +
Math.pow(hitPose.transform.position.z - camera.position.z, 2)
);
return distance < 2; // Only consider hits within 2 meters
});
if (filteredResults.length > 0) {
const hit = filteredResults[0];
const hitPose = hit.getPose(xrSession.referenceSpace);
if (hitPose) {
// Update object position based on the filtered result
virtualObject.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z);
virtualObject.quaternion.set(hitPose.transform.orientation.x, hitPose.transform.orientation.y, hitPose.transform.orientation.z, hitPose.transform.orientation.w);
}
}
}
Utilisation de différents espaces de référence
Le choix de l’espace de référence (viewerSpace, local, localFloor ou d’autres espaces personnalisés) a un impact significatif sur la façon dont les résultats des tests de collision sont interprétés. Tenez compte des points suivants :
- viewerSpace : fournit des résultats par rapport à la position du spectateur. Ceci est utile pour créer des interactions directement liées au regard de l’utilisateur.
- local : fournit des résultats par rapport à l’origine XR (le point de départ de la session XR). Ceci est adapté à la création d’expériences où les objets restent fixes dans l’environnement physique.
- localFloor : semblable Ă
local, mais l’axe Y est aligné sur le sol. Cela simplifie le processus de placement d’objets sur le sol.
Choisissez l’espace de référence qui correspond le mieux aux exigences de votre application. Expérimentez avec différents espaces de référence pour comprendre leur comportement et leurs limites.
Stratégies d’optimisation pour les tests de collision
Le test de collision peut être un processus gourmand en calcul, en particulier dans les scènes complexes. Voici quelques stratégies d’optimisation à prendre en compte :
- Limiter la fréquence des tests de collision : effectuez des tests de collision uniquement lorsque cela est nécessaire, plutôt qu’à chaque image. Par exemple, vous pouvez effectuer des tests de collision uniquement lorsque l’utilisateur interagit activement avec la scène.
- Utiliser une hiérarchie d’arborescence englobante (BVH) : si vous effectuez des tests de collision sur un grand nombre d’objets, envisagez d’utiliser une BVH pour accélérer les calculs d’intersection. Les bibliothèques telles que three.js et Babylon.js fournissent des implémentations BVH intégrées.
- Partitionnement spatial : divisez la scène en régions plus petites et effectuez des tests de collision uniquement sur les régions susceptibles de contenir des intersections. Cela peut réduire considérablement le nombre d’objets à vérifier.
- Réduire le nombre de polygones : simplifiez la géométrie de vos modèles pour réduire le nombre de polygones à tester. Cela peut améliorer les performances, en particulier sur les appareils mobiles.
- WebWorker : déchargez le calcul sur un Web Worker pour vous assurer que le processus de test de collision ne verrouille pas le thread principal.
Considérations interplateformes
WebXR vise à être multiplateforme, mais il peut y avoir de subtiles différences de comportement entre différents appareils et navigateurs. Gardez les points suivants à l’esprit :
- Capacités de l’appareil : tous les appareils ne prennent pas en charge toutes les fonctionnalités WebXR. Utilisez la détection de fonctionnalité pour déterminer quelles fonctionnalités sont disponibles et adaptez votre application en conséquence.
- Profils d’entrée : différents appareils peuvent utiliser différents profils d’entrée (par exemple, écran tactile générique, suivi de la main, manette de jeu). Assurez-vous que votre application prend en charge plusieurs profils d’entrée et fournit des mécanismes de secours appropriés.
- Performances : les performances peuvent varier considérablement entre différents appareils. Optimisez votre application pour les appareils d’entrée de gamme que vous prévoyez de prendre en charge.
- Compatibilité du navigateur : assurez-vous que votre application est testée et fonctionne sur les principaux navigateurs tels que Chrome, Firefox et Edge.
Exemples mondiaux d’applications WebXR utilisant des tests de collision
Voici quelques exemples d’applications WebXR qui utilisent efficacement les tests de collision pour créer des expériences utilisateur convaincantes et intuitives :
- IKEA Place (Suède) : permet aux utilisateurs de placer virtuellement des meubles IKEA dans leurs maisons à l’aide de la RA. Les tests de collision sont utilisés pour positionner avec précision les meubles sur le sol et d’autres surfaces.
- Sketchfab AR (France) : permet aux utilisateurs d’afficher des modèles 3D de Sketchfab dans la RA. Les tests de collision sont utilisés pour placer les modèles dans le monde réel.
- Images augmentées (divers) : de nombreuses applications de RA utilisent le suivi d’image combiné au test de collision pour ancrer le contenu virtuel à des images ou des marqueurs spécifiques dans le monde réel.
- Jeux WebXR (mondial) : de nombreux jeux sont en cours de développement à l’aide de WebXR, dont beaucoup reposent sur des tests de collision pour le placement d’objets, l’interaction et la navigation.
- Visites virtuelles (mondial) : les visites immersives de lieux, de musées ou de propriétés utilisent souvent des tests de collision pour la navigation des utilisateurs et les éléments interactifs dans l’environnement virtuel.
Conclusion
La maîtrise des résultats des tests de collision WebXR et du traitement du lancer de rayon est essentielle pour créer des expériences RA et RV convaincantes et intuitives sur le Web. En comprenant les concepts sous-jacents et en appliquant les techniques décrites dans cet article de blog, vous pouvez créer des applications immersives qui mélangent de manière transparente les mondes virtuel et réel, ou créer des environnements virtuels engageants avec des interactions utilisateur naturelles et intuitives. N’oubliez pas d’optimiser votre implémentation de test de collision pour les performances et de tenir compte de la compatibilité multiplateforme afin de garantir une expérience fluide à tous les utilisateurs. À mesure que l’écosystème WebXR continue d’évoluer, attendez-vous à d’autres avancées et améliorations de l’API de test de collision, ouvrant ainsi des possibilités encore plus créatives pour le développement Web immersif. Consultez toujours les dernières spécifications WebXR et la documentation du navigateur pour obtenir les informations les plus récentes.