Bu sayfa, WebXR'yi kullanarak basit bir etkileyici AR uygulaması oluşturma konusunda size yol gösterecektir.
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()
çağıran bir düğme oluşturun. Kullanıcı sayfayı yükledikten sonra bu düğmeyi kullanarak AR deneyimini başlatabilir.
index.html
adında yeni bir dosya oluşturun ve 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>
Two.js'yi başlatma
Başlat düğmesine basıldığında fazla bir şey olmaz. 3D ortam oluşturmak için, bir sahneyi görüntülemek üzere oluşturma kitaplığı kullanabilirsiniz.
Bu örnekte, WebGL oluşturucu sağlayan three.js
adlı JavaScript 3D oluşturma kitaplığını kullanacaksınız. Three.js
; oluşturma, kameralar ve sahne grafiklerini yöneterek web'de 3D içeriğin görüntülenmesini kolaylaştırır.
Sahne oluşturma
3D ortam genellikle sahne olarak modellenir. AR öğeleri içeren bir THREE.Scene
oluşturun.
Aşağıdaki kod, artırılmış gerçeklik (AR) modunda ışığı yanmayan renkli bir kutuya bakmanıza olanak tanır.
activateXR()
işlevinin en altına şu kodu 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 artırılmış gerçeklikte (AR) görüntüleyebilmek için bir oluşturucuya ve kameraya ihtiyacınız vardır. 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.
activateXR()
işlevinin en altına şu kodu 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()
üzerinden. Oluşturulan içeriğin gerçek dünyada görüntülenmesini sağlamak için immersive-ar
modunu kullanın.
XRReferenceSpace
, sanal dünyadaki nesneler için kullanılan koordinat sistemini tanımlar.
'local'
modu, kaynağı görüntüleyiciye yakın olan bir referans alanı ve kararlı takibiyle en çok artırılmış gerçeklik (AR) deneyimi için uygundur.
XRSession
ve XRReferenceSpace
oluşturmak için activateXR()
işlevinin alt kısmına şu 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ştur
Artık sahneyi oluşturabilirsiniz. XRSession.requestAnimationFrame()
, tarayıcı çerçeve çizmeye hazır olduğunda yürütülecek bir geri çağırma planlar.
Animasyon çerçevesi geri çağırma işlemi sırasında, izleyicinin pozunu yerel koordinat alanına göre elde etmek için XRFrame.getViewerPose()
yöntemini çağırın.
Bu, sahne içi kamerayı güncellemek için kullanılır ve oluşturucu, güncellenmiş kamerayı kullanarak sahneyi çizmeden önce kullanıcının sanal dünyayı görüntüleme şeklini değiştirir.
activateXR()
işlevinin en altına şu kodu 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'yi çalıştır
Cihazınızda WebXR dosyasına gidin. Renkli bir küpü her yönden görüntüleyebilmeniz gerekir.
İsabet testi ekle
AR dünyasıyla etkileşimde bulunmanın yaygın bir yolu, ışın ve gerçek geometrinin kesişimini bulan isabet testidir. Hello WebXR'de sanal dünyaya ayçiçeği yerleştirmek için bir isabet testi kullanacaksınız.
Demo küpü kaldırın
Aydınlatılmayan küpü kaldırıp ışık 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 isteğinde bulunun. Önceki requestSession()
parçasını bulun ve hit-test
parçasını ekleyin:
const session = await navigator.xr.requestSession("immersive-ar", {requiredFeatures: ['hit-test']});
Model yükleyici ekle
Şu an için sahnede yalnızca renkli bir küp bulunmaktadır. Deneyimi daha ilgi çekici hale getirmek için GLTF modellerinin yüklenmesine olanak tanıyan bir model yükleyici ekleyin.
Dokümanınızın <head>
etiketine three.js' GLTFLoader
ifadesini 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 modellerini yükleme
Web'den bir hedefleme retikülü ve ayçiçeği yüklemek için önceki adımda bulunan model yükleyiciyi kullanın.
Bu kodu onXRFrame
kodunun üzerine 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 nesnelerle kesişimleri hesaplamak için XRSession.requestHitTestSource()
kullanarak bir XRHitTestSource
oluşturun.
İsabet testi için kullanılan ışın, kaynak olarak viewer
referans alanına sahiptir, yani isabet testi görüntü alanının merkezinden yapılır.
İ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 retikülü çizme
Ayçiçeğinin yerleştirileceği yeri netleştirmek için sahneye bir hedefleme retikülasyonu ekleyin. Bu manşet, gerçek dünyadaki yüzeylere yapışarak ayçiçeğinin demir atacağı yeri belirtir.
XRFrame.getHitTestResults
, bir XRHitTestResult
dizisi döndürür ve gerçek geometriye sahip kesişimleri gösterir.
Hedefleme noktasını her kareye konumlandırmak için bu kesişimleri 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);
}
Dokunulduğunda etkileşimler ekleniyor
XRSession
, kullanıcı birincil işlemi tamamladığında select
etkinlik alır.
Artırılmış gerçeklik oturumunda bu, ekrana dokunulmasına karşılık gelir.
Başlatma sırasında şu kodu ekleyerek kullanıcı ekrana dokunduğunda yeni bir ayçiçeğin 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 retikül gerçek dünyadaki yüzeylerde görünmelidir. Tüm yönlerden görülebilen ayçiçeği yerleştirmek için ekrana dokunun.