Cómo mi juego de navegador se ejecuta en RV en un Meta Quest
Mi juego Bannermarch se ejecuta en el navegador y, como ahora es 3D, quería ver si podía jugarlo en RV. Se puede. Me puse mis Meta Quest, abrí el juego en el navegador del casco y presioné un botón que dice Entrar en RV. Entonces estaba de pie dentro de los terrenos de mi castillo, con la torre principal (la torre principal) en lo alto de la colina frente a mí. No instalé nada. Es la misma página web que abrirías en un portátil.
Esto funciona por dos motivos. Los navegadores tienen una API integrada para cascos de RV llamada WebXR, y el juego ya utiliza Babylon.js, un motor 3D que sabe cómo usarla.
Cómo el navegador hace RV
WebXR permite que una página web hable con un casco de RV. El navegador Quest lo tiene, al igual que Chrome y Edge en un ordenador con un casco de RV para PC conectado. Safari en el iPhone no.
Primero, la página pregunta al navegador si la RV está disponible. Si lo está, la página muestra un botón Entrar en RV. Tienes que hacer clic en algo para iniciar la RV, porque los navegadores no permiten que una página lo haga por sí sola (es la misma regla que impide que los vídeos se reproduzcan automáticamente con sonido).
Después de hacer clic, el navegador se encarga de la pantalla del casco. Muchas veces por segundo, le dice a la página dónde están tu cabeza y tus manos. Luego, la página dibuja el juego dos veces, una para cada ojo, cada una desde un punto ligeramente diferente. Esa pequeña diferencia es lo que hace que las cosas parezcan 3D en el casco.
// WebXR normal, sin motor
if (await navigator.xr?.isSessionSupported("immersive-vr")) {
button.onclick = async () => {
const session = await navigator.xr.requestSession("immersive-vr");
const space = await session.requestReferenceSpace("local-floor");
session.requestAnimationFrame(function frame(time, xrFrame) {
const pose = xrFrame.getViewerPose(space);
for (const view of pose.views) {
// dibuja la escena con view.transform y view.projectionMatrix
}
session.requestAnimationFrame(frame);
});
};
}
La parte local-floor le dice al navegador que coloque el suelo del juego donde está tu suelo real, para que veas el mundo desde tu propia altura.
El navegador se encarga de las partes difíciles, como el seguimiento de tu cabeza y el ajuste de la imagen a las lentes. El juego solo dibuja lo que ve la cámara.
Cómo ayuda Babylon.js
No escribí ese código yo mismo. Babylon.js tiene una utilidad llamada WebXRDefaultExperience que lo hace por ti. Inicia la sesión de RV y mueve la cámara cuando mueves la cabeza. También te proporciona punteros láser en los mandos y te permite teletransportarte. Esta es aproximadamente toda la configuración que necesitaba.
const xr = await WebXRDefaultExperience.CreateAsync(scene, {
disableDefaultUI: true,
floorMeshes: [ground],
disableHandTracking: true,
inputOptions: {
doNotLoadControllerMeshes: true,
disableOnlineControllerRepository: true,
},
teleportationOptions: { forceHandedness: "right" },
});
// más tarde, desde el botón Entrar en RV
await xr.baseExperience.enterXRAsync("immersive-vr", "local-floor");
No tuve que cambiar el juego en sí. Es el mismo mundo 3D que ves en un portátil, con los mismos edificios, personas y barcos. Si apuntas a un edificio y aprietas el gatillo, su nombre aparece encima. Vuelve a apretar el gatillo y el juego te saca de la RV con el menú de ese edificio abierto. Gestionar tu castillo sigue siendo más fácil en una pantalla normal.
Las personas en teléfonos y portátiles no descargan nada del código de RV. Solo se carga en dispositivos que pueden usarlo.
Qué salió mal
No funcionó al primer intento. Los joysticks de los mandos no hacían nada al principio. Babylon descarga un archivo para cada mando que indica qué botones tiene, pero la configuración de seguridad de mi sitio bloquea esa descarga. Sin el archivo, Babylon trataba los mandos como si solo tuvieran un gatillo. Lo solucioné poniendo esos archivos dentro del juego para que no necesite descargarlos.
Cuando añadí la opción de caminar con el stick izquierdo, el botón Entrar en RV desapareció. La caminata integrada de Babylon no se puede activar al mismo tiempo que el teletransporte, por lo que la configuración de RV falló. Escribí mi propia caminata en su lugar, unas 30 líneas de código. El stick izquierdo te hace caminar hacia donde miras, y el stick derecho te teletransporta o te gira en pasos. Dejé de lado el giro suave porque hace que mucha gente se maree.
Los colores se veían mal en el casco. El juego ajusta sus colores como último paso en la cámara normal, y ese paso no se ejecuta en la cámara de RV, así que tuve que aplicarlo de otra manera en RV.
El juego también se congeló tan pronto como entré en RV. Para ahorrar batería, deja de dibujar cuando cambias a otra pestaña. El navegador Quest le dijo al juego que su pestaña estaba oculta mientras estaba en RV, por lo que el juego se detuvo. Ahora sigue dibujando mientras la RV está activada.
El chip gráfico del Quest es tan potente como el de un teléfono, y tiene que dibujar todo dos veces, por lo que utiliza la configuración gráfica baja del juego. Algunos teléfonos también dicen que admiten RV (para visores de cartón), por lo que solo muestro el botón en cascos y ordenadores.
Iniciar sesión fue un problema aparte, ya que escribir una contraseña en un teclado flotante es doloroso. Escribí sobre cómo lo resolví en iniciar sesión en un casco de RV como lo hace tu TV.