WebXR kullanarak etkileyici AR oturumu oluşturma

Bu sayfada, WebXR'yi kullanarak basit bir tam sayfa AR uygulaması oluşturma konusunda size yol gösterilmektedir.

Başlamak için WebXR uyumlu bir geliştirme ortamına ihtiyacınız vardır.

HTML sayfası oluşturma

WebXR'nin oturum başlatabilmesi için kullanıcı etkileşimi gerekir. activateXR() işlevini çağıran bir düğme oluşturun. Sayfa yüklendikten sonra kullanıcı, AR deneyimini başlatmak için bu düğmeyi kullanabilir.

index.html adlı yeni bir dosya oluşturun ve dosyaya aşağıdaki HTML kodunu ekleyin:

<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <title>Hello WebXR!</title>

  <!-- three.js -->
  <script src="https://unpkg.com/three@0.126.0/build/three.js"></script>
</head>
<body>

<!-- Starting an immersive WebXR session requires user interaction.
    We start this one with a simple button. -->
<button onclick="activateXR()">Start Hello WebXR</button>
<script>
async function activateXR() {
  // Add a canvas element and initialize a WebGL context that is compatible with WebXR.
  const canvas = document.createElement("canvas");
  document.body.appendChild(canvas);
  const gl = canvas.getContext("webgl", {xrCompatible: true});

  // To be continued in upcoming steps.
}
</script>
</body>
</html>

three.js'yi başlatma

Başlat düğmesine bastığınızda pek bir şey olmaz. 3D ortam oluşturmak için bir sahneyi görüntülemek üzere oluşturma kitaplığı kullanabilirsiniz.

Bu örnekte, WebGL oluşturma aracı sağlayan bir JavaScript 3D oluşturma kitaplığı olan three.js'i kullanacaksınız. Three.js, oluşturma, kameralar ve sahne grafiklerini yöneterek 3D içeriğin web'de gösterilmesini kolaylaştırır.

Sahne oluşturma

3D ortamlar genellikle sahne olarak modellenir. AR öğeleri içeren bir THREE.Scene oluşturun. Aşağıdaki kod, AR'da ışıksız renkli bir kutuya bakmanızı sağlar.

Aşağıdaki kodu activateXR() işlevinin altına ekleyin:

const scene = new THREE.Scene();

// The cube will have a different color on each side.
const materials = [
  new THREE.MeshBasicMaterial({color: 0xff0000}),
  new THREE.MeshBasicMaterial({color: 0x0000ff}),
  new THREE.MeshBasicMaterial({color: 0x00ff00}),
  new THREE.MeshBasicMaterial({color: 0xff00ff}),
  new THREE.MeshBasicMaterial({color: 0x00ffff}),
  new THREE.MeshBasicMaterial({color: 0xffff00})
];

// Create the cube and add it to the demo scene.
const cube = new THREE.Mesh(new THREE.BoxBufferGeometry(0.2, 0.2, 0.2), materials);
cube.position.set(1, 1, 1);
scene.add(cube);

three.js kullanarak oluşturmayı ayarlama

Bu sahneyi AR'da görüntülemek için bir oluşturucu ve kamera gerekir. Oluşturucu, sahnenizi ekrana çizmek için WebGL'yi kullanır. Kamera, sahnenin görüntülendiği görüntü alanını tanımlar.

Aşağıdaki kodu activateXR() işlevinin altına ekleyin:

// Set up the WebGLRenderer, which handles rendering to the session's base layer.
const renderer = new THREE.WebGLRenderer({
  alpha: true,
  preserveDrawingBuffer: true,
  canvas: canvas,
  context: gl
});
renderer.autoClear = false;

// The API directly updates the camera matrices.
// Disable matrix auto updates so three.js doesn't attempt
// to handle the matrices independently.
const camera = new THREE.PerspectiveCamera();
camera.matrixAutoUpdate = false;

XRSession oluşturma

WebXR'ye giriş noktası XRSystem.requestSession() üzerindendir. Oluşturulan içeriğin gerçek dünyada görüntülenmesine izin vermek için immersive-ar modunu kullanın.

XRReferenceSpace, sanal dünyadaki nesneler için kullanılan koordinat sistemini tanımlar. 'local' modu, izleyiciye yakın bir orijine ve kararlı izlemeye sahip bir referans alanıyla AR deneyimi için en uygun moddur.

XRSession ve XRReferenceSpace oluşturmak için activateXR() işlevinin altına aşağıdaki kodu ekleyin:

// Initialize a WebXR session using "immersive-ar".
const session = await navigator.xr.requestSession("immersive-ar");
session.updateRenderState({
  baseLayer: new XRWebGLLayer(session, gl)
});

// A 'local' reference space has a native origin that is located
// near the viewer's position at the time the session was created.
const referenceSpace = await session.requestReferenceSpace('local');

Sahneyi oluşturma

Artık sahneyi oluşturabilirsiniz. XRSession.requestAnimationFrame(), tarayıcı bir çerçeve çizmeye hazır olduğunda çalıştırılacak bir geri çağırma işlevi planlar.

Animasyon karesi geri çağırması sırasında, izleyicinin yerel koordinat alanına göre duruşunu elde etmek için XRFrame.getViewerPose() işlevini çağırın. Bu, sahnedeki kamerayı güncellemek için kullanılır. Böylece, oluşturucu güncellenmiş kamerayı kullanarak sahneyi çizmeden önce kullanıcının sanal dünyayı görüntüleme şekli değiştirilir.

Aşağıdaki kodu activateXR() işlevinin altına ekleyin:

// Create a render loop that allows us to draw on the AR view.
const onXRFrame = (time, frame) => {
  // Queue up the next draw request.
  session.requestAnimationFrame(onXRFrame);

  // Bind the graphics framebuffer to the baseLayer's framebuffer
  gl.bindFramebuffer(gl.FRAMEBUFFER, session.renderState.baseLayer.framebuffer)

  // Retrieve the pose of the device.
  // XRFrame.getViewerPose can return null while the session attempts to establish tracking.
  const pose = frame.getViewerPose(referenceSpace);
  if (pose) {
    // In mobile AR, we only have one view.
    const view = pose.views[0];

    const viewport = session.renderState.baseLayer.getViewport(view);
    renderer.setSize(viewport.width, viewport.height)

    // Use the view's transform matrix and projection matrix to configure the THREE.camera.
    camera.matrix.fromArray(view.transform.matrix)
    camera.projectionMatrix.fromArray(view.projectionMatrix);
    camera.updateMatrixWorld(true);

    // Render the scene with THREE.WebGLRenderer.
    renderer.render(scene, camera)
  }
}
session.requestAnimationFrame(onXRFrame);

Hello WebXR'ı çalıştırma

Cihazınızda WebXR dosyasına gidin. Renkli bir küpü her yönden görebilmeniz gerekir.

İsabet testi ekleme

Artırılmış gerçeklik dünyasıyla etkileşime geçmenin yaygın bir yolu, bir ışın ile gerçek dünya geometrisi arasında kesişim bulan isabetçi testi kullanmaktır. Hello WebXR'da, sanal dünyaya bir ayçiçeği yerleştirmek için isabet testi kullanacaksınız.

Demo kübünü kaldırma

Işıklandırılmamış küpü kaldırın ve ışıklandırma içeren bir sahneyle değiştirin:

const scene = new THREE.Scene();

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.3);
directionalLight.position.set(10, 15, 10);
scene.add(directionalLight);

hit-test özelliğini kullanma

İsabet testi işlevini başlatmak için hit-test özelliğiyle oturum isteyin. Önceki requestSession() fragmanını bulun ve hit-test ekleyin:

const session = await navigator.xr.requestSession("immersive-ar", {requiredFeatures: ['hit-test']});

Model yükleyici ekleme

Şu anda sahnede yalnızca renkli bir küp bulunuyor. Deneyimi daha ilgi çekici hale getirmek için GLTF modellerinin yüklenmesine olanak tanıyan bir model yükleyici ekleyin.

Belgenizin <head> etiketine three.js'in GLTFLoader öğesini ekleyin.

<!-- three.js -->
<script src="https://unpkg.com/three@0.126.0/build/three.js"></script>

<script src="https://unpkg.com/three@0.126.0/examples/js/loaders/GLTFLoader.js"></script>

GLTF modelleri yükleme

Web'den bir hedefleme nişangahı ve ayçiçeği yüklemek için önceki adımdaki model yükleyiciyi kullanın.

onXRFrame kodunun üzerine şu kodu ekleyin:

const loader = new THREE.GLTFLoader();
let reticle;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/reticle/reticle.gltf", function(gltf) {
  reticle = gltf.scene;
  reticle.visible = false;
  scene.add(reticle);
})

let flower;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/sunflower.gltf", function(gltf) {
  flower = gltf.scene;
});

// Create a render loop that allows us to draw on the AR view.
const onXRFrame = (time, frame) => {

İsabet testi kaynağı oluşturma

Gerçek dünyadaki nesnelerle kesişim noktalarını hesaplamak için XRSession.requestHitTestSource() kullanarak bir XRHitTestSource oluşturun. İsabet testi için kullanılan ışın, orijin olarak viewer referans alanını kullanır. Bu, isabet testinin görüntü alanının ortasından yapıldığı anlamına gelir.

İsabet testi kaynağı oluşturmak için local referans alanını oluşturduktan sonra şu kodu ekleyin:

// A 'local' reference space has a native origin that is located
// near the viewer's position at the time the session was created.
const referenceSpace = await session.requestReferenceSpace('local');

// Create another XRReferenceSpace that has the viewer as the origin.
const viewerSpace = await session.requestReferenceSpace('viewer');
// Perform hit testing using the viewer as origin.
const hitTestSource = await session.requestHitTestSource({ space: viewerSpace });

Hedefleme nişangahı çizme

Ayçiçeğinin nereye yerleştirileceğini netleştirmek için sahneye bir hedefleme nişangahı ekleyin. Bu nişangah, gerçek dünyadaki yüzeylere yapışmış gibi görünür ve ayçiçeğinin sabitleneceği yeri gösterir.

XRFrame.getHitTestResults, bir XRHitTestResult dizisi döndürür ve kesişimleri gerçek dünya geometrisiyle gösterir. Hedefleme nişangahını her karede konumlandırmak için bu kesişim noktalarını kullanın.

camera.projectionMatrix.fromArray(view.projectionMatrix);
camera.updateMatrixWorld(true);

const hitTestResults = frame.getHitTestResults(hitTestSource);
if (hitTestResults.length > 0 && reticle) {
  const hitPose = hitTestResults[0].getPose(referenceSpace);
  reticle.visible = true;
  reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z)
  reticle.updateMatrixWorld(true);
}

Dokunma etkileşimi ekleme

Kullanıcı bir birincil işlemi tamamladığında XRSession, select etkinliği alır. Bu, AR oturumunda ekrana dokunmaya karşılık gelir.

İlk başlatma sırasında bu kodu ekleyerek kullanıcı ekrana dokunduğunda yeni bir ayçiçeği görünmesini sağlayın:

let flower;
loader.load("https://immersive-web.github.io/webxr-samples/media/gltf/sunflower/sunflower.gltf", function(gltf) {
  flower = gltf.scene;
});

session.addEventListener("select", (event) => {
  if (flower) {
    const clone = flower.clone();
    clone.position.copy(reticle.position);
    scene.add(clone);
  }
});

İsabet testini test etme

Sayfaya gitmek için mobil cihazınızı kullanın. WebXR, çevreyi anladıktan sonra gerçek dünyadaki yüzeylerde nişangah gösterilir. Ekranı dokunarak her yönden görülebilen bir ayçiçeği yerleştirin.

Sonraki adımlar