{"id":28127,"date":"2022-08-15T07:03:47","date_gmt":"2022-08-15T07:03:47","guid":{"rendered":"http:\/\/an-introductory-guide-to-webxr"},"modified":"2022-08-15T07:03:47","modified_gmt":"2022-08-15T07:03:47","slug":"an-introductory-guide-to-webxr","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/","title":{"rendered":"An Introductory Guide to WebXR"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>XR stands for Extended Reality. WebXR Device API provides access to input and output capabilities commonly associated with Virtual Reality (VR) and Augmented Reality (AR) devices. It allows you develop and host VR and AR experiences on the web.\nIn this post, we will be learning about WebXR, how it works on the browser, and how to build our first VR application with React and WebXR.<\/p>\n<p>The WebXR Device API is an API designed to access the sensors and displays of immersive hardware hardware such as VR headsets, augmented reality headsets, and a wide range of immersive devices. It. works by knowing what the user is looking at from the devices sensors.<\/p>\n<h2>Examples of WebXR<\/h2>\n<p>Some instances where WebXR can be deployed to are:<\/p>\n<ul>\n<li>360deg and 3D videos<\/li>\n<li>3D object and data visualization<\/li>\n<li>Artistic experiences<\/li>\n<\/ul>\n<h2>How to build a WebXR Experience<\/h2>\n<p>WebXR is a WebGL (Web Graphics Library) based API. This means you can\u2019t render 3D experience with HTML and CSS, it\u2019s purely restricted to WebGL. <strong>WebGL<\/strong> is a JavaScript API for rendering high-performance interactive 3D and 2D graphics within any compatible web browser without the use of plug-ins.\nThe bad news is that WebGL is very verbose, it takes a lot of work to just render a simple cube. The good news is we have some JavaScript libraries that abstracts all that complexity. Some of those libraries are: <a href=\"https:\/\/playcanvas.com\/\">PlayCanvas<\/a>, <a href=\"https:\/\/threejs.org\/\">three.js<\/a>, <a href=\"https:\/\/aframe.io\/\">A-FRAME<\/a>, <a href=\"https:\/\/www.babylonjs.com\/\">babylonjs<\/a>, <a href=\"https:\/\/docs.pmnd.rs\/react-three-fiber\/getting-started\/introduction\">react-three-fiber<\/a>, <a href=\"https:\/\/github.com\/pmndrs\/react-xr\">react-xr,<\/a> e.t.c\n<a href=\"https:\/\/threejs.org\/\"><\/a>\nLet\u2019s go ahead and build a 3D scene with some object using react-three-fiber.<\/p>\n<h2>Building 3D scene with react-three-fiber<\/h2>\n<p>React-three-fiber is a JavaScript library for creating 360degree immersive VR experiences. It uses the same declarative concepts in React and use the threejs engine for 3D rendering. <code>react-three-fiber<\/code> is an abstracts the complexity of threejs and makes it more accessible for React developers to build VR experiences.\n<strong>Pre-requisites<\/strong>\nYou would need to have the following to flow with this guide:<\/p>\n<ul>\n<li>Nodejs &gt;=v14 installed<\/li>\n<li>Knowledge of JavaScript and React<\/li>\n<li>A code editor (preferably VS Code)<\/li>\n<li>Basic Threejs knowledge. Go through <a href=\"https:\/\/threejs.org\/docs\/index.html#manual\/en\/introduction\/Creating-a-scene\">this<\/a>.<\/li>\n<li>Basic knowledge of react-three-fiber. Go through the <a href=\"https:\/\/docs.pmnd.rs\/react-three-fiber\/getting-started\/introduction\">documentation<\/a>\n<\/li>\n<\/ul>\n<p>The complete code for this article is on <a href=\"https:\/\/codesandbox.io\/embed\/amazing-jones-sxh83d?autoresize=1&amp;fontsize=14&amp;hidenavigation=1&amp;theme=dark\">CodeSandbox<\/a>.<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/amazing-jones-sxh83d?theme=dark&amp;codemirror=1&amp;highlights=&amp;editorsize=50&amp;fontsize=14&amp;expanddevtools=0&amp;hidedevtools=0&amp;eslint=0&amp;forcerefresh=0&amp;hidenavigation=0&amp;initialpath=%2F&amp;module=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"amazing-jones-sxh83d?\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n  <div class=\"wp-block-cloudinary-markdown \"><p><strong>Getting Started<\/strong>\nLet\u2019s get started by creating a React app with <code>create-react-app<\/code>. Run this command on your terminal:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">npx create-react-app react-xr-app\n<\/code><\/span><\/pre>\n<p>When it\u2019s done installing, open the project directory with your code editor.\nGo ahead and delete all the files from the src folder except <code>App.js<\/code> and <code>index.js<\/code>.\nInstall the following packages:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">npm<\/span> <span class=\"hljs-selector-tag\">install<\/span> <span class=\"hljs-selector-tag\">three<\/span> <span class=\"hljs-keyword\">@react-three<\/span>\/fiber @react-three\/drei lamina react-merge-refs\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Now paste this code snippet<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/This code is gotten from Three.js templates <\/span>\n<span class=\"hljs-comment\">\/\/App.js<\/span>\n<span class=\"hljs-keyword\">import<\/span> * <span class=\"hljs-keyword\">as<\/span> THREE <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'three'<\/span>\n<span class=\"hljs-keyword\">import<\/span> { Canvas } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@react-three\/fiber'<\/span>\n<span class=\"hljs-keyword\">import<\/span> { Sparkles, Shadow, ContactShadows, Billboard, Environment, BakeShadows, OrbitControls } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@react-three\/drei'<\/span>\n<span class=\"hljs-keyword\">import<\/span> { LayerMaterial, Depth } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'lamina'<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ env = <span class=\"hljs-string\">'https:\/\/res.cloudinary.com\/sammy365\/raw\/upload\/v1658828418\/nat-callaghan-GOxq9KQBSw0-unsplash_lu0jbk.hdr'<\/span> }<\/span>) =&gt;<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">style<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">height:<\/span> \"<span class=\"hljs-attr\">80vh<\/span>\" }}&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Canvas<\/span> <span class=\"hljs-attr\">shadows<\/span> <span class=\"hljs-attr\">camera<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">position:<\/span> &#91;<span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">12<\/span>], <span class=\"hljs-attr\">fov:<\/span> <span class=\"hljs-attr\">60<\/span> }} <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"800\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">hemisphereLight<\/span> <span class=\"hljs-attr\">intensity<\/span>=<span class=\"hljs-string\">{0.5}<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">\"white\"<\/span> <span class=\"hljs-attr\">groundColor<\/span>=<span class=\"hljs-string\">\"black\"<\/span> \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Environment<\/span> <span class=\"hljs-attr\">files<\/span>=<span class=\"hljs-string\">{env}<\/span> <span class=\"hljs-attr\">ground<\/span>=<span class=\"hljs-string\">{{<\/span> <span class=\"hljs-attr\">height:<\/span> <span class=\"hljs-attr\">5<\/span>, <span class=\"hljs-attr\">radius:<\/span> <span class=\"hljs-attr\">40<\/span>, <span class=\"hljs-attr\">scale:<\/span> <span class=\"hljs-attr\">20<\/span> }} \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Sphere<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">\"white\"<\/span> <span class=\"hljs-attr\">amount<\/span>=<span class=\"hljs-string\">{50}<\/span> <span class=\"hljs-attr\">emissive<\/span>=<span class=\"hljs-string\">\"green\"<\/span> <span class=\"hljs-attr\">glow<\/span>=<span class=\"hljs-string\">\"lightgreen\"<\/span> <span class=\"hljs-attr\">position<\/span>=<span class=\"hljs-string\">{&#91;1,<\/span> <span class=\"hljs-attr\">1<\/span>, <span class=\"hljs-attr\">-1<\/span>]} \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Sphere<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">\"white\"<\/span> <span class=\"hljs-attr\">amount<\/span>=<span class=\"hljs-string\">{30}<\/span> <span class=\"hljs-attr\">emissive<\/span>=<span class=\"hljs-string\">\"purple\"<\/span> <span class=\"hljs-attr\">glow<\/span>=<span class=\"hljs-string\">\"#ff90f0\"<\/span> <span class=\"hljs-attr\">size<\/span>=<span class=\"hljs-string\">{0.5}<\/span> <span class=\"hljs-attr\">position<\/span>=<span class=\"hljs-string\">{&#91;-1.5,<\/span> <span class=\"hljs-attr\">0.5<\/span>, <span class=\"hljs-attr\">-2<\/span>]} \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Sphere<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">\"lightpink\"<\/span> <span class=\"hljs-attr\">amount<\/span>=<span class=\"hljs-string\">{20}<\/span> <span class=\"hljs-attr\">emissive<\/span>=<span class=\"hljs-string\">\"orange\"<\/span> <span class=\"hljs-attr\">glow<\/span>=<span class=\"hljs-string\">\"#ff9f50\"<\/span> <span class=\"hljs-attr\">size<\/span>=<span class=\"hljs-string\">{0.25}<\/span> <span class=\"hljs-attr\">position<\/span>=<span class=\"hljs-string\">{&#91;-1,<\/span> <span class=\"hljs-attr\">0.25<\/span>, <span class=\"hljs-attr\">1<\/span>]} \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ContactShadows<\/span> <span class=\"hljs-attr\">renderOrder<\/span>=<span class=\"hljs-string\">{2}<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">\"black\"<\/span> <span class=\"hljs-attr\">resolution<\/span>=<span class=\"hljs-string\">{1024}<\/span> <span class=\"hljs-attr\">frames<\/span>=<span class=\"hljs-string\">{1}<\/span> <span class=\"hljs-attr\">scale<\/span>=<span class=\"hljs-string\">{10}<\/span> <span class=\"hljs-attr\">blur<\/span>=<span class=\"hljs-string\">{1.5}<\/span> <span class=\"hljs-attr\">opacity<\/span>=<span class=\"hljs-string\">{0.65}<\/span> <span class=\"hljs-attr\">far<\/span>=<span class=\"hljs-string\">{0.5}<\/span> \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">BakeShadows<\/span> \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">OrbitControls<\/span> <span class=\"hljs-attr\">autoRotateSpeed<\/span>=<span class=\"hljs-string\">{0.85}<\/span> <span class=\"hljs-attr\">zoomSpeed<\/span>=<span class=\"hljs-string\">{0.75}<\/span> <span class=\"hljs-attr\">minPolarAngle<\/span>=<span class=\"hljs-string\">{Math.PI<\/span> \/ <span class=\"hljs-attr\">2.5<\/span>} <span class=\"hljs-attr\">maxPolarAngle<\/span>=<span class=\"hljs-string\">{Math.PI<\/span> \/ <span class=\"hljs-attr\">2.55<\/span>} \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Canvas<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n)\n\n<span class=\"hljs-keyword\">const<\/span> Sphere = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ size = <span class=\"hljs-number\">1<\/span>, amount = <span class=\"hljs-number\">50<\/span>, color = <span class=\"hljs-string\">'white'<\/span>, emissive, glow, ...props }<\/span>) =&gt;<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">mesh<\/span> {<span class=\"hljs-attr\">...props<\/span>}&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">sphereGeometry<\/span> <span class=\"hljs-attr\">args<\/span>=<span class=\"hljs-string\">{&#91;size,<\/span> <span class=\"hljs-attr\">64<\/span>, <span class=\"hljs-attr\">64<\/span>]} \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meshPhysicalMaterial<\/span> <span class=\"hljs-attr\">roughness<\/span>=<span class=\"hljs-string\">{0}<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">emissive<\/span>=<span class=\"hljs-string\">{emissive<\/span> || <span class=\"hljs-attr\">color<\/span>} <span class=\"hljs-attr\">envMapIntensity<\/span>=<span class=\"hljs-string\">{0.2}<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Glow<\/span> <span class=\"hljs-attr\">scale<\/span>=<span class=\"hljs-string\">{size<\/span> * <span class=\"hljs-attr\">1.2<\/span>} <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{-25}<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">{glow<\/span> || <span class=\"hljs-attr\">emissive<\/span> || <span class=\"hljs-attr\">color<\/span>} \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Sparkles<\/span> <span class=\"hljs-attr\">count<\/span>=<span class=\"hljs-string\">{amount}<\/span> <span class=\"hljs-attr\">scale<\/span>=<span class=\"hljs-string\">{size<\/span> * <span class=\"hljs-attr\">2<\/span>} <span class=\"hljs-attr\">size<\/span>=<span class=\"hljs-string\">{6}<\/span> <span class=\"hljs-attr\">speed<\/span>=<span class=\"hljs-string\">{0.4}<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Shadow<\/span> <span class=\"hljs-attr\">rotation<\/span>=<span class=\"hljs-string\">{&#91;-Math.PI<\/span> \/ <span class=\"hljs-attr\">2<\/span>, <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} <span class=\"hljs-attr\">scale<\/span>=<span class=\"hljs-string\">{size}<\/span> <span class=\"hljs-attr\">position<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">-size<\/span>, <span class=\"hljs-attr\">0<\/span>]} <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">{emissive}<\/span> <span class=\"hljs-attr\">opacity<\/span>=<span class=\"hljs-string\">{0.5}<\/span> \/&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">mesh<\/span>&gt;<\/span><\/span>\n)\n\n<span class=\"hljs-keyword\">const<\/span> Glow = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ color, scale = <span class=\"hljs-number\">0.5<\/span>, near = <span class=\"hljs-number\">-2<\/span>, far = <span class=\"hljs-number\">1.4<\/span> }<\/span>) =&gt;<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Billboard<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">mesh<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">circleGeometry<\/span> <span class=\"hljs-attr\">args<\/span>=<span class=\"hljs-string\">{&#91;2<\/span> * <span class=\"hljs-attr\">scale<\/span>, <span class=\"hljs-attr\">16<\/span>]} \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">LayerMaterial<\/span>\n        <span class=\"hljs-attr\">transparent<\/span>\n        <span class=\"hljs-attr\">depthWrite<\/span>=<span class=\"hljs-string\">{false}<\/span>\n        <span class=\"hljs-attr\">blending<\/span>=<span class=\"hljs-string\">{THREE.CustomBlending}<\/span>\n        <span class=\"hljs-attr\">blendEquation<\/span>=<span class=\"hljs-string\">{THREE.AddEquation}<\/span>\n        <span class=\"hljs-attr\">blendSrc<\/span>=<span class=\"hljs-string\">{THREE.SrcAlphaFactor}<\/span>\n        <span class=\"hljs-attr\">blendDst<\/span>=<span class=\"hljs-string\">{THREE.DstAlphaFactor}<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Depth<\/span> <span class=\"hljs-attr\">colorA<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">colorB<\/span>=<span class=\"hljs-string\">\"black\"<\/span> <span class=\"hljs-attr\">alpha<\/span>=<span class=\"hljs-string\">{1}<\/span> <span class=\"hljs-attr\">mode<\/span>=<span class=\"hljs-string\">\"normal\"<\/span> <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{near<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">far<\/span>=<span class=\"hljs-string\">{far<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">origin<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Depth<\/span> <span class=\"hljs-attr\">colorA<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">colorB<\/span>=<span class=\"hljs-string\">\"black\"<\/span> <span class=\"hljs-attr\">alpha<\/span>=<span class=\"hljs-string\">{0.5}<\/span> <span class=\"hljs-attr\">mode<\/span>=<span class=\"hljs-string\">\"add\"<\/span> <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{-40<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">far<\/span>=<span class=\"hljs-string\">{far<\/span> * <span class=\"hljs-attr\">1.2<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">origin<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Depth<\/span> <span class=\"hljs-attr\">colorA<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">colorB<\/span>=<span class=\"hljs-string\">\"black\"<\/span> <span class=\"hljs-attr\">alpha<\/span>=<span class=\"hljs-string\">{1}<\/span> <span class=\"hljs-attr\">mode<\/span>=<span class=\"hljs-string\">\"add\"<\/span> <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{-15<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">far<\/span>=<span class=\"hljs-string\">{far<\/span> * <span class=\"hljs-attr\">0.7<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">origin<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Depth<\/span> <span class=\"hljs-attr\">colorA<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">colorB<\/span>=<span class=\"hljs-string\">\"black\"<\/span> <span class=\"hljs-attr\">alpha<\/span>=<span class=\"hljs-string\">{1}<\/span> <span class=\"hljs-attr\">mode<\/span>=<span class=\"hljs-string\">\"add\"<\/span> <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{-10<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">far<\/span>=<span class=\"hljs-string\">{far<\/span> * <span class=\"hljs-attr\">0.68<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">origin<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">LayerMaterial<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">mesh<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Billboard<\/span>&gt;<\/span><\/span>\n)\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Here, we start by creating the environment with <code>react-fiber<\/code> <code>Canvas<\/code>. If you notice, you can see a cloudinary image, that 3D image will be represented as our 3D environment.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Sphere<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">\"white\"<\/span> <span class=\"hljs-attr\">amount<\/span>=<span class=\"hljs-string\">{50}<\/span> <span class=\"hljs-attr\">emissive<\/span>=<span class=\"hljs-string\">\"green\"<\/span> <span class=\"hljs-attr\">glow<\/span>=<span class=\"hljs-string\">\"lightgreen\"<\/span> <span class=\"hljs-attr\">position<\/span>=<span class=\"hljs-string\">{&#91;1,<\/span> <span class=\"hljs-attr\">1<\/span>, <span class=\"hljs-attr\">-1<\/span>]} \/&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Sphere<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">\"white\"<\/span> <span class=\"hljs-attr\">amount<\/span>=<span class=\"hljs-string\">{30}<\/span> <span class=\"hljs-attr\">emissive<\/span>=<span class=\"hljs-string\">\"purple\"<\/span> <span class=\"hljs-attr\">glow<\/span>=<span class=\"hljs-string\">\"#ff90f0\"<\/span> <span class=\"hljs-attr\">size<\/span>=<span class=\"hljs-string\">{0.5}<\/span> <span class=\"hljs-attr\">position<\/span>=<span class=\"hljs-string\">{&#91;-1.5,<\/span> <span class=\"hljs-attr\">0.5<\/span>, <span class=\"hljs-attr\">-2<\/span>]} \/&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Sphere<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">\"lightpink\"<\/span> <span class=\"hljs-attr\">amount<\/span>=<span class=\"hljs-string\">{20}<\/span> <span class=\"hljs-attr\">emissive<\/span>=<span class=\"hljs-string\">\"orange\"<\/span> <span class=\"hljs-attr\">glow<\/span>=<span class=\"hljs-string\">\"#ff9f50\"<\/span> <span class=\"hljs-attr\">size<\/span>=<span class=\"hljs-string\">{0.25}<\/span> <span class=\"hljs-attr\">position<\/span>=<span class=\"hljs-string\">{&#91;-1,<\/span> <span class=\"hljs-attr\">0.25<\/span>, <span class=\"hljs-attr\">1<\/span>]} \/&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> Sphere = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ size = <span class=\"hljs-number\">1<\/span>, amount = <span class=\"hljs-number\">50<\/span>, color = <span class=\"hljs-string\">'white'<\/span>, emissive, glow, ...props }<\/span>) =&gt;<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">mesh<\/span> {<span class=\"hljs-attr\">...props<\/span>}&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">sphereGeometry<\/span> <span class=\"hljs-attr\">args<\/span>=<span class=\"hljs-string\">{&#91;size,<\/span> <span class=\"hljs-attr\">64<\/span>, <span class=\"hljs-attr\">64<\/span>]} \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meshPhysicalMaterial<\/span> <span class=\"hljs-attr\">roughness<\/span>=<span class=\"hljs-string\">{0}<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">emissive<\/span>=<span class=\"hljs-string\">{emissive<\/span> || <span class=\"hljs-attr\">color<\/span>} <span class=\"hljs-attr\">envMapIntensity<\/span>=<span class=\"hljs-string\">{0.2}<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Glow<\/span> <span class=\"hljs-attr\">scale<\/span>=<span class=\"hljs-string\">{size<\/span> * <span class=\"hljs-attr\">1.2<\/span>} <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{-25}<\/span> <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">{glow<\/span> || <span class=\"hljs-attr\">emissive<\/span> || <span class=\"hljs-attr\">color<\/span>} \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Sparkles<\/span> <span class=\"hljs-attr\">count<\/span>=<span class=\"hljs-string\">{amount}<\/span> <span class=\"hljs-attr\">scale<\/span>=<span class=\"hljs-string\">{size<\/span> * <span class=\"hljs-attr\">2<\/span>} <span class=\"hljs-attr\">size<\/span>=<span class=\"hljs-string\">{6}<\/span> <span class=\"hljs-attr\">speed<\/span>=<span class=\"hljs-string\">{0.4}<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Shadow<\/span> <span class=\"hljs-attr\">rotation<\/span>=<span class=\"hljs-string\">{&#91;-Math.PI<\/span> \/ <span class=\"hljs-attr\">2<\/span>, <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} <span class=\"hljs-attr\">scale<\/span>=<span class=\"hljs-string\">{size}<\/span> <span class=\"hljs-attr\">position<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">-size<\/span>, <span class=\"hljs-attr\">0<\/span>]} <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">{emissive}<\/span> <span class=\"hljs-attr\">opacity<\/span>=<span class=\"hljs-string\">{0.5}<\/span> \/&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">mesh<\/span>&gt;<\/span><\/span>\n)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>This snippet renders the Spheres. There is a Glow effect on the Spheres, this part of the code implements that:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> Glow = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ color, scale = <span class=\"hljs-number\">0.5<\/span>, near = <span class=\"hljs-number\">-2<\/span>, far = <span class=\"hljs-number\">1.4<\/span> }<\/span>) =&gt;<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Billboard<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">mesh<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">circleGeometry<\/span> <span class=\"hljs-attr\">args<\/span>=<span class=\"hljs-string\">{&#91;2<\/span> * <span class=\"hljs-attr\">scale<\/span>, <span class=\"hljs-attr\">16<\/span>]} \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">LayerMaterial<\/span>\n        <span class=\"hljs-attr\">transparent<\/span>\n        <span class=\"hljs-attr\">depthWrite<\/span>=<span class=\"hljs-string\">{false}<\/span>\n        <span class=\"hljs-attr\">blending<\/span>=<span class=\"hljs-string\">{THREE.CustomBlending}<\/span>\n        <span class=\"hljs-attr\">blendEquation<\/span>=<span class=\"hljs-string\">{THREE.AddEquation}<\/span>\n        <span class=\"hljs-attr\">blendSrc<\/span>=<span class=\"hljs-string\">{THREE.SrcAlphaFactor}<\/span>\n        <span class=\"hljs-attr\">blendDst<\/span>=<span class=\"hljs-string\">{THREE.DstAlphaFactor}<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Depth<\/span> <span class=\"hljs-attr\">colorA<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">colorB<\/span>=<span class=\"hljs-string\">\"black\"<\/span> <span class=\"hljs-attr\">alpha<\/span>=<span class=\"hljs-string\">{1}<\/span> <span class=\"hljs-attr\">mode<\/span>=<span class=\"hljs-string\">\"normal\"<\/span> <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{near<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">far<\/span>=<span class=\"hljs-string\">{far<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">origin<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Depth<\/span> <span class=\"hljs-attr\">colorA<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">colorB<\/span>=<span class=\"hljs-string\">\"black\"<\/span> <span class=\"hljs-attr\">alpha<\/span>=<span class=\"hljs-string\">{0.5}<\/span> <span class=\"hljs-attr\">mode<\/span>=<span class=\"hljs-string\">\"add\"<\/span> <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{-40<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">far<\/span>=<span class=\"hljs-string\">{far<\/span> * <span class=\"hljs-attr\">1.2<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">origin<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Depth<\/span> <span class=\"hljs-attr\">colorA<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">colorB<\/span>=<span class=\"hljs-string\">\"black\"<\/span> <span class=\"hljs-attr\">alpha<\/span>=<span class=\"hljs-string\">{1}<\/span> <span class=\"hljs-attr\">mode<\/span>=<span class=\"hljs-string\">\"add\"<\/span> <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{-15<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">far<\/span>=<span class=\"hljs-string\">{far<\/span> * <span class=\"hljs-attr\">0.7<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">origin<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} \/&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Depth<\/span> <span class=\"hljs-attr\">colorA<\/span>=<span class=\"hljs-string\">{color}<\/span> <span class=\"hljs-attr\">colorB<\/span>=<span class=\"hljs-string\">\"black\"<\/span> <span class=\"hljs-attr\">alpha<\/span>=<span class=\"hljs-string\">{1}<\/span> <span class=\"hljs-attr\">mode<\/span>=<span class=\"hljs-string\">\"add\"<\/span> <span class=\"hljs-attr\">near<\/span>=<span class=\"hljs-string\">{-10<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">far<\/span>=<span class=\"hljs-string\">{far<\/span> * <span class=\"hljs-attr\">0.68<\/span> * <span class=\"hljs-attr\">scale<\/span>} <span class=\"hljs-attr\">origin<\/span>=<span class=\"hljs-string\">{&#91;0,<\/span> <span class=\"hljs-attr\">0<\/span>, <span class=\"hljs-attr\">0<\/span>]} \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">LayerMaterial<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">mesh<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Billboard<\/span>&gt;<\/span><\/span>\n)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_88F13895AFBB4182C7D1FC27775986826EBFF6E1D82CE6370AF0110D5F8D8F99_1659341960294_Screenshot+2022-08-01+at+09.19.05.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"849\"\/><\/p>\n<p>This line of code adds the rotating orbit effect<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">OrbitControls<\/span> <span class=\"hljs-attr\">autoRotateSpeed<\/span>=<span class=\"hljs-string\">{0.85}<\/span> <span class=\"hljs-attr\">zoomSpeed<\/span>=<span class=\"hljs-string\">{0.75}<\/span> <span class=\"hljs-attr\">minPolarAngle<\/span>=<span class=\"hljs-string\">{Math.PI<\/span> \/ <span class=\"hljs-attr\">2.5<\/span>} <span class=\"hljs-attr\">maxPolarAngle<\/span>=<span class=\"hljs-string\">{Math.PI<\/span> \/ <span class=\"hljs-attr\">2.55<\/span>} \/&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>If you followed the links on the pre-requisites, you\u2019ll have a fair understanding of what\u2019s going on here.\nSave and run your app with <code>npm run start<\/code>. Navigate to <code>http:\/\/localhost:3000<\/code> on your browser and you will be presented with this screen:<\/p>\n<p><a href=\"https:\/\/www.dropbox.com\/s\/8ige6ek8uielelv\/webxr.webm?dl=0\">https:\/\/www.dropbox.com\/s\/8ige6ek8uielelv\/webxr.webm?dl=0<\/a><\/p>\n<p>Awesome.\nYou can find more examples using react-three-fiber <a href=\"https:\/\/docs.pmnd.rs\/react-three-fiber\/getting-started\/examples\">here<\/a>.<\/p>\n<h2>Future of WebXR Device API<\/h2>\n<p>The WebXR Devive API is still on active development, these are some features we expect to come soon:<\/p>\n<ul>\n<li>DOM Overlay API for better accessibility<\/li>\n<li>Lighting estimation using Computer vision<\/li>\n<li>Hand interactions.<\/li>\n<\/ul>\n<h2>Conclusion<\/h2>\n<p>In this article, we introduced the WebXR Device API by explaining what it is, we also outlined some examples where WebXR can be deployed to and we discussed how to build a WebXR experience. We went further to explore a React library that abstracts three.js rendering engine called <code>react-three-fiber<\/code>. We went on to build a simple sample app with the library and concluded with highlighting WebXR features we are to expecting soon.\nI hope you picked up a thing or two from this article.<\/p>\n<p>Happy Coding!<\/p>\n<h2>Further Reading<\/h2>\n<ul>\n<li>\n<a href=\"https:\/\/immersiveweb.dev\/\">Immersive-web Github Readme<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/WebXR_Device_API\">WebXR Device API MDN<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/docs.pmnd.rs\/react-three-fiber\/getting-started\/introduction\">React three fiber documentation<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/threejs.org\/\">three.js<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28128,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,177,246,371],"class_list":["post-28127","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-javascript","tag-react","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>An Introductory Guide to WebXR<\/title>\n<meta name=\"description\" content=\"XR stands for Extended Reality. WebXR Device API provides access to input and output capabilities commonly associated with Virtual Reality (VR) and Augmented Reality (AR) devices. It allows you develop and host VR and AR experiences on the web. In this post, we will be learning about WebXR, how it works on the browser, and how to build our first VR application with React and WebXR.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"An Introductory Guide to WebXR\" \/>\n<meta property=\"og:description\" content=\"XR stands for Extended Reality. WebXR Device API provides access to input and output capabilities commonly associated with Virtual Reality (VR) and Augmented Reality (AR) devices. It allows you develop and host VR and AR experiences on the web. In this post, we will be learning about WebXR, how it works on the browser, and how to build our first VR application with React and WebXR.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-08-15T07:03:47+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"An Introductory Guide to WebXR\",\"datePublished\":\"2022-08-15T07:03:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/\"},\"wordCount\":5,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA\",\"keywords\":[\"Guest Post\",\"Javascript\",\"React\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/\",\"name\":\"An Introductory Guide to WebXR\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA\",\"datePublished\":\"2022-08-15T07:03:47+00:00\",\"description\":\"XR stands for Extended Reality. WebXR Device API provides access to input and output capabilities commonly associated with Virtual Reality (VR) and Augmented Reality (AR) devices. It allows you develop and host VR and AR experiences on the web. In this post, we will be learning about WebXR, how it works on the browser, and how to build our first VR application with React and WebXR.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA\",\"width\":1721,\"height\":771},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"An Introductory Guide to WebXR\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"An Introductory Guide to WebXR","description":"XR stands for Extended Reality. WebXR Device API provides access to input and output capabilities commonly associated with Virtual Reality (VR) and Augmented Reality (AR) devices. It allows you develop and host VR and AR experiences on the web. In this post, we will be learning about WebXR, how it works on the browser, and how to build our first VR application with React and WebXR.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/","og_locale":"en_US","og_type":"article","og_title":"An Introductory Guide to WebXR","og_description":"XR stands for Extended Reality. WebXR Device API provides access to input and output capabilities commonly associated with Virtual Reality (VR) and Augmented Reality (AR) devices. It allows you develop and host VR and AR experiences on the web. In this post, we will be learning about WebXR, how it works on the browser, and how to build our first VR application with React and WebXR.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/","og_site_name":"Cloudinary Blog","article_published_time":"2022-08-15T07:03:47+00:00","twitter_card":"summary_large_image","twitter_image":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/"},"author":{"name":"","@id":""},"headline":"An Introductory Guide to WebXR","datePublished":"2022-08-15T07:03:47+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/"},"wordCount":5,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA","keywords":["Guest Post","Javascript","React","Under Review"],"inLanguage":"en-US","copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/","name":"An Introductory Guide to WebXR","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA","datePublished":"2022-08-15T07:03:47+00:00","description":"XR stands for Extended Reality. WebXR Device API provides access to input and output capabilities commonly associated with Virtual Reality (VR) and Augmented Reality (AR) devices. It allows you develop and host VR and AR experiences on the web. In this post, we will be learning about WebXR, how it works on the browser, and how to build our first VR application with React and WebXR.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA","width":1721,"height":771},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/an-introductory-guide-to-webxr\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"An Introductory Guide to WebXR"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681922303\/Web_Assets\/blog\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118\/dbf6f01ce609a335985984e19ae134f703ca257b-1721x771-1_28128c5118.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=28127"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28127\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28128"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}