WebXRããããã¹ãçµæãšã¬ã€ãã£ã¹ãã£ã³ã°åŠçã®è©³çްããŠã§ãäžã§ã€ã³ã¿ã©ã¯ãã£ãã§çŽæçãªæ¡åŒµçŸå®ããã³ä»®æ³çŸå®äœéšãäœæããããã«äžå¯æ¬ ã§ãã
WebXRããããã¹ãçµæïŒæ²¡å ¥åäœéšã®ããã®ã¬ã€ãã£ã¹ãã£ã³ã°çµæåŠç
WebXR Device APIã¯ããã©ãŠã¶å ã§çŽæ¥æ²¡å ¥åã®æ¡åŒµçŸå®ïŒARïŒããã³ä»®æ³çŸå®ïŒVRïŒäœéšãäœæããããã®ãšããµã€ãã£ã³ã°ãªå¯èœæ§ãåãéããŸããã€ã³ã¿ã©ã¯ãã£ããªWebXRã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããäžã§åºæ¬çãªåŽé¢ã®1ã€ã¯ãããããã¹ãçµæãçè§£ãã广çã«å©çšããããšã§ãããã®ããã°æçš¿ã§ã¯ãã¬ã€ãã£ã¹ãã£ã³ã°ãéããŠååŸãããããããã¹ãçµæãåŠçããããã®å æ¬çãªã¬ã€ããæäŸããWebXRã·ãŒã³å ã§çŽæçã§é åçãªãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãäœæã§ããããã«ããŸãã
ã¬ã€ãã£ã¹ãã£ã³ã°ãšã¯äœãïŒãªãWebXRã§éèŠãªã®ãïŒ
ã¬ã€ãã£ã¹ãã£ã³ã°ã¯ãç¹å®ã®ç¹ãšæ¹åããçºããããã¬ã€ãã3Dã·ãŒã³å ã®ãªããžã§ã¯ããšäº€å·®ãããã©ããã倿ããããã«äœ¿çšãããææ³ã§ããWebXRã§ã¯ãã¬ã€ãã£ã¹ãã£ã³ã°ã¯éåžžããŠãŒã¶ãŒã®èŠç·ãŸãã¯ä»®æ³ãªããžã§ã¯ãã®è»éãã·ãã¥ã¬ãŒãããããã«äœ¿çšãããŸããã¬ã€ãçŸå®äžçã®ãµãŒãã§ã¹ïŒARã®å ŽåïŒãŸãã¯ä»®æ³ãªããžã§ã¯ãïŒVRã®å ŽåïŒãšäº€å·®ãããšãããããã¹ãçµæãçæãããŸãã
ããããã¹ãçµæã¯ãããã€ãã®çç±ã§éèŠã§ãã
- ä»®æ³ãªããžã§ã¯ãã®é 眮ïŒARã§ã¯ãããããã¹ãã䜿çšãããšãããŒãã«ãåºãå£ãªã©ã®çŸå®äžçã®ãµãŒãã§ã¹äžã«ä»®æ³ãªããžã§ã¯ããæ£ç¢ºã«é 眮ã§ããŸãã
- ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ïŒãŠãŒã¶ãŒãèŠãŠããå ŽæãŸãã¯æããŠããå Žæã远跡ããããšã§ãããããã¹ãã«ãããéžæãæäœããŸãã¯ã¢ã¯ãã£ãåãªã©ã®ä»®æ³ãªããžã§ã¯ããšã®ã€ã³ã¿ã©ã¯ã·ã§ã³ãå¯èœã«ãªããŸãã
- ããã²ãŒã·ã§ã³ïŒVRç°å¢ã§ã¯ãããããã¹ãã䜿çšããŠããã²ãŒã·ã§ã³ã·ã¹ãã ãå®è£ ãããŠãŒã¶ãŒãç¹å®ã®å Žæãæãããšã«ãã£ãŠãã·ãŒã³å ããã¬ããŒããŸãã¯ç§»åã§ããããã«ããããšãã§ããŸãã
- è¡çªæ€åºïŒããããã¹ãã¯åºæ¬çãªè¡çªæ€åºã«äœ¿çšã§ããä»®æ³ãªããžã§ã¯ããå¥ã®ãªããžã§ã¯ããŸãã¯çŸå®äžçãšè¡çªããã¿ã€ãã³ã°ã倿ã§ããŸãã
WebXRããããã¹ãAPIã®çè§£
WebXRããããã¹ãAPIã¯ãã¬ã€ãã£ã¹ãã£ã³ã°ãå®è¡ããããããã¹ãçµæãååŸããããã«å¿ èŠãªããŒã«ãæäŸããŸããäž»èŠãªæŠå¿µãšé¢æ°ã以äžã«ç€ºããŸãã
XRRay
XRRayã¯ã3D空éå
ã®ã¬ã€ã衚ããŸããããã¯ãåç¹ãšæ¹åãã¯ãã«ã«ãã£ãŠå®çŸ©ãããŸããXRFrame.getPose()ã¡ãœããã䜿çšããŠXRRayãäœæã§ããŸãããã®ã¡ãœããã¯ã远跡ãããå
¥åãœãŒã¹ïŒãŠãŒã¶ãŒã®é ããã³ãã³ã³ãããŒã©ãŒãªã©ïŒã®ããŒãºãè¿ããŸããããŒãºãããã¬ã€ã®åç¹ãšæ¹åãå°ãåºãããšãã§ããŸãã
XRHitTestSource
XRHitTestSourceã¯ãããããã¹ãçµæã®ãœãŒã¹ã衚ããŸããXRSession.requestHitTestSource()ãŸãã¯XRSession.requestHitTestSourceForTransientInput()ã¡ãœããã䜿çšããŠãããããã¹ããœãŒã¹ãäœæããŸããæåã®ã¡ãœããã¯éåžžããŠãŒã¶ãŒã®é ã®äœçœ®ãªã©ã®æ°žç¶çãªãœãŒã¹ã«åºã¥ããŠç¶ç¶çãªããããã¹ãã«äœ¿çšãããã®ã«å¯Ÿãã2çªç®ã®ã¡ãœããã¯ããã¿ã³ã®æŒäžããžã§ã¹ãã£ãŒãªã©ã®äžæçãªå
¥åã€ãã³ãã察象ãšããŠããŸãã
XRHitTestResult
XRHitTestResultã¯ãã¬ã€ãšãµãŒãã§ã¹éã®åäžã®äº€ç¹ã衚ããŸããã¬ã€ã®åç¹ããããããã€ã³ããŸã§ã®è·é¢ãããã³ã·ãŒã³ã®åç
§ç©ºéå
ã®ããããã€ã³ãã®ããŒãºãªã©ã亀ç¹ã«é¢ããæ
å ±ãå«ãŸããŠããŸãã
XRHitTestResult.getPose()
ãã®ã¡ãœããã¯ãããããã€ã³ãã®XRPoseãè¿ããŸããããŒãºã«ã¯ãããããã€ã³ãã®äœçœ®ãšåããå«ãŸããŠãããä»®æ³ãªããžã§ã¯ããé
眮ããããä»ã®å€æãå®è¡ãããããããã«äœ¿çšã§ããŸãã
ããããã¹ãçµæã®åŠçïŒã¹ãããããšã®ã¬ã€ã
WebXRã¢ããªã±ãŒã·ã§ã³ã§ããããã¹ãçµæãååŸããŠåŠçããããã»ã¹ãèŠãŠãããŸãããããã®äŸã§ã¯ãthree.jsãBabylon.jsãªã©ã®ã¬ã³ããªã³ã°ã©ã€ãã©ãªã䜿çšããŠããããšãåæãšããŠããŸãã
1. ããããã¹ããœãŒã¹ã®ãªã¯ãšã¹ã
ãŸããXRSessionããããããã¹ããœãŒã¹ããªã¯ãšã¹ãããå¿
èŠããããŸããããã¯éåžžãã»ãã·ã§ã³ãéå§ãããåŸã«è¡ãããŸããããããã¹ãçµæãè¿ã座æšç³»ãæå®ããå¿
èŠããããŸããäŸïŒ
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);
説æïŒ
xrSession.requestHitTestSource()ïŒãã®é¢æ°ã¯ãXRã»ãã·ã§ã³ããããããã¹ããœãŒã¹ããªã¯ãšã¹ãããŸãã{ space: xrSession.viewerSpace }ïŒããã¯ãããããã¹ãçµæãè¿ããã座æšç³»ãæå®ããŸããviewerSpaceã¯ãã¥ãŒã¢ãŒã®äœçœ®ãåºæºãšããlocalã¯XRåç¹ãåºæºãšããŠããŸããåºãåºæºã«è¿œè·¡ããã«ã¯ãlocalFloorã䜿çšã§ããŸãã- ãšã©ãŒåŠçïŒ
try...catchãããã¯ã¯ãããããã¹ããœãŒã¹ã®äœæäžã«ãšã©ãŒãçºçããå Žåã«ããšã©ãŒããã£ãããããŠãã°ã«èšé²ãããããã«ããŸãã
2. ã¢ãã¡ãŒã·ã§ã³ã«ãŒãã§ã®ããããã¹ãã®å®è¡
ã¢ãã¡ãŒã·ã§ã³ã«ãŒãïŒåãã¬ãŒã ãã¬ã³ããªã³ã°ãã颿°ïŒå
ã§ãXRFrame.getHitTestResults()ã¡ãœããã䜿çšããŠããããã¹ããå®è¡ããå¿
èŠããããŸãããã®ã¡ãœããã¯ãã·ãŒã³å
ã§èŠã€ãã£ããã¹ãŠã®äº€ç¹ã衚ãXRHitTestResultãªããžã§ã¯ãã®é
åãè¿ããŸãã
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);
}
説æïŒ
frame.getViewerPose(xrSession.referenceSpace)ïŒãã¥ãŒã¢ãŒïŒãããã»ããïŒã®ããŒãºãååŸããŸããããã¯ããã¥ãŒã¢ãŒãã©ãã«ããŠãã©ããèŠãŠããããç¥ãããã«å¿ èŠã§ããframe.getHitTestResults(xrHitTestSource)ïŒä»¥åã«äœæããããããã¹ããœãŒã¹ã䜿çšããŠããããã¹ããå®è¡ããŸããhitTestResults.length > 0ïŒäº€ç¹ãèŠã€ãã£ããã©ããã確èªããŸãã
3. ããããã¹ãçµæã®åŠç
processHitTestResults()颿°ã¯ãããããã¹ãã®çµæãåŠçããå Žæã§ããéåžžãããã«ã¯ãããããã€ã³ãã®ããŒãºã«åºã¥ããŠä»®æ³ãªããžã§ã¯ãã®äœçœ®ãšåããæŽæ°ããããšãå«ãŸããŸãã
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;
}
}
説æïŒ
hitTestResults[0]ïŒæåã®ããããã¹ãçµæãååŸããŸããè€æ°ã®äº€å·®ãå¯èœã§ããå Žåã¯ãé åå šäœãå埩åŠçããã¢ããªã±ãŒã·ã§ã³ã®ããžãã¯ã«åºã¥ããŠæé©ãªçµæãéžæããå¿ èŠãããå ŽåããããŸããhit.getPose(xrSession.referenceSpace)ïŒæå®ãããåç §ç©ºéå ã®ããããã€ã³ãã®ããŒãºãååŸããŸããvirtualObject.position.set(...)ããã³virtualObject.quaternion.set(...)ïŒããããã€ã³ãã®ããŒãºã«åãããŠãä»®æ³ãªããžã§ã¯ãïŒthree.jsã®Meshãªã©ïŒã®äœçœ®ãšå転ïŒã¯ã©ãŒã¿ããªã³ïŒãæŽæ°ããŸãã- èŠèŠçãªãã£ãŒãããã¯ïŒãã®äŸã«ã¯ããŠãŒã¶ãŒãã·ãŒã³ãšã®ã€ã³ã¿ã©ã¯ã·ã§ã³ã®å Žæãçè§£ããã®ã«åœ¹ç«ã€ããã«ãããããã€ã³ãã«åãŸãã¯åçŽãªããŒã«ãŒãªã©ã®èŠèŠçãªãã£ãŒãããã¯ã衚瀺ããã³ãŒããå«ãŸããŠããŸãã
é«åºŠãªããããã¹ããã¯ããã¯
äžèšã®åºæ¬çãªäŸãè¶ ããŠãããããã¹ãã®å®è£ ã匷åããããã«äœ¿çšã§ããé«åºŠãªãã¯ããã¯ãããã€ããããŸãã
äžæçãªå ¥åã䜿çšããããããã¹ã
ãã¿ã³ã®æŒäžããã³ããžã§ã¹ãã£ãŒãªã©ãäžæçãªå
¥åã«ãã£ãŠããªã¬ãŒãããã€ã³ã¿ã©ã¯ã·ã§ã³ã®å ŽåãXRSession.requestHitTestSourceForTransientInput()ã¡ãœããã䜿çšã§ããŸãããã®ã¡ãœããã¯ãåäžã®å
¥åã€ãã³ãã«åºæã®ããããã¹ããœãŒã¹ãäœæããŸããããã¯ãç¶ç¶çãªããããã¹ãã«åºã¥ããŠæå³ããªãã€ã³ã¿ã©ã¯ã·ã§ã³ãåé¿ããã®ã«åœ¹ç«ã¡ãŸãã
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);
ããããã¹ãçµæã®ãã£ã«ã¿ãªã³ã°
å Žåã«ãã£ãŠã¯ãã¬ã€ã®åç¹ããã®è·é¢ã亀差ãããµãŒãã§ã¹ã®çš®é¡ãªã©ãç¹å®ã®åºæºã«åºã¥ããŠããããã¹ãçµæããã£ã«ã¿ãªã³ã°ããå¿
èŠãããå ŽåããããŸãããããè¡ãã«ã¯ãååŸåŸã«XRHitTestResulté
åãæåã§ãã£ã«ã¿ãªã³ã°ããŸãã
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);
}
}
}
ç°ãªãåç §ç©ºéã®äœ¿çš
åç
§ç©ºéã®éžæïŒviewerSpaceãlocalãlocalFloorããŸãã¯ãã®ä»ã®ã«ã¹ã¿ã 空éïŒã¯ãããããã¹ãçµæã®è§£éæ¹æ³ã«å€§ãã圱é¿ããŸãã以äžãæ€èšããŠãã ããã
- viewerSpaceïŒãã¥ãŒã¢ãŒã®äœçœ®ãåºæºãšããçµæãæäŸããŸããããã¯ããŠãŒã¶ãŒã®èŠç·ã«çŽæ¥çµã³ä»ããããã€ã³ã¿ã©ã¯ã·ã§ã³ãäœæããã®ã«åœ¹ç«ã¡ãŸãã
- localïŒXRåç¹ïŒXRã»ãã·ã§ã³ã®éå§ç¹ïŒãåºæºãšããçµæãæäŸããŸããããã¯ããªããžã§ã¯ããç©çç°å¢å ã§åºå®ããããŸãŸã«ãªããšã¯ã¹ããªãšã³ã¹ãäœæããã®ã«é©ããŠããŸãã
- localFloorïŒ
localã«äŒŒãŠããŸãããY軞ãåºã«æããããŠããŸããããã«ããããªããžã§ã¯ããåºã«é 眮ããããã»ã¹ãç°¡çŽ åãããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®èŠä»¶ã«æé©ãªåç §ç©ºéãéžæããŠãã ãããããŸããŸãªåç §ç©ºéã詊ããŠããã®åäœãšå¶éãçè§£ããŠãã ããã
ããããã¹ãã®æé©åæŠç¥
ããããã¹ãã¯ãç¹ã«è€éãªã·ãŒã³ã§ã¯ãèšç®è² è·ã®é«ãããã»ã¹ã«ãªãå¯èœæ§ããããŸããæ€èšãã¹ãæé©åæŠç¥ãããã€ã瀺ããŸãã
- ããããã¹ãã®é »åºŠãå¶éããïŒæ¯åãã¬ãŒã ãå®è¡ããã®ã§ã¯ãªããå¿ èŠãªå Žåã«ã®ã¿ããããã¹ããå®è¡ããŸããããšãã°ããŠãŒã¶ãŒãã·ãŒã³ãšç©æ¥µçã«å¯Ÿè©±ããŠããå Žåã«ã®ã¿ãããããã¹ããå®è¡ã§ããŸãã
- ããŠã³ãã£ã³ã°ããªã¥ãŒã éå±€ïŒBVHïŒã䜿çšããïŒå€æ°ã®ãªããžã§ã¯ãã«å¯ŸããŠããããã¹ããå®è¡ããå Žåã¯ãBVHã䜿çšããŠäº€å·®èšç®ãé«éåããããšãæ€èšããŠãã ããã three.jsãBabylon.jsãªã©ã®ã©ã€ãã©ãªã«ã¯ãçµã¿èŸŒã¿ã®BVHå®è£ ãçšæãããŠããŸãã
- 空éåå²ïŒã·ãŒã³ãããå°ããªé åã«åå²ãã亀差ãå«ãŸããå¯èœæ§ã®é«ãé åã«å¯ŸããŠã®ã¿ããããã¹ããå®è¡ããŸããããã«ããã確èªããå¿ èŠããããªããžã§ã¯ãã®æ°ãå€§å¹ ã«æžããããšãã§ããŸãã
- ããªãŽã³æ°ãæžããïŒãã¹ãããå¿ èŠãããããªãŽã³ã®æ°ãæžããããã«ãã¢ãã«ã®ãžãªã¡ããªãç°¡ç¥åããŸããããã¯ãç¹ã«ã¢ãã€ã«ããã€ã¹ã§ããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãã
- WebWorkerïŒèšç®ãWebã¯ãŒã«ãŒã«ãªãããŒãããŠãããããã¹ãããã»ã¹ãã¡ã€ã³ã¹ã¬ãããããã¯ããªãããã«ããŸãã
ã¯ãã¹ãã©ãããã©ãŒã ã«é¢ããèæ ®äºé
WebXRã¯ã¯ãã¹ãã©ãããã©ãŒã ãç®æããŠããŸãããããã€ã¹ããã©ãŠã¶ã«ãã£ãŠåäœã«åŸ®åŠãªéããããå ŽåããããŸããæ¬¡ã®ç¹ã«æ³šæããŠãã ããã
- ããã€ã¹ã®æ©èœïŒãã¹ãŠã®ããã€ã¹ããã¹ãŠã®WebXRæ©èœããµããŒãããŠããããã§ã¯ãããŸãããæ©èœæ€åºã䜿çšããŠãã©ã®æ©èœãå©çšå¯èœãã倿ããããã«å¿ããŠã¢ããªã±ãŒã·ã§ã³ã調æŽããŸãã
- å ¥åãããã¡ã€ã«ïŒããã€ã¹ã«ãã£ãŠãç°ãªãå ¥åãããã¡ã€ã«ïŒgeneric-touchscreenããã³ããã©ããã³ã°ãã²ãŒã ããããªã©ïŒã䜿çšããå ŽåããããŸããã¢ããªã±ãŒã·ã§ã³ãè€æ°ã®å ¥åãããã¡ã€ã«ããµããŒãããé©åãªãã©ãŒã«ããã¯ã¡ã«ããºã ãæäŸããŠããããšã確èªããŠãã ããã
- ããã©ãŒãã³ã¹ïŒããã©ãŒãã³ã¹ã¯ãããã€ã¹ã«ãã£ãŠå€§ããç°ãªãå ŽåããããŸãããµããŒãããäºå®ã®æãããŒãšã³ãã®ããã€ã¹ã«åãããŠã¢ããªã±ãŒã·ã§ã³ãæé©åããŠãã ããã
- ãã©ãŠã¶ã®äºææ§ïŒã¢ããªããã¹ããããChromeãFirefoxãEdgeãªã©ã®äž»èŠãªãã©ãŠã¶ã§åäœããããšã確èªããŸãã
ããããã¹ãã䜿çšããWebXRã¢ããªã±ãŒã·ã§ã³ã®ã°ããŒãã«ãªäŸ
ããããã¹ãã广çã«å©çšããŠãé åçã§çŽæçãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãäœæããŠããWebXRã¢ããªã±ãŒã·ã§ã³ã®äŸã次ã«ç€ºããŸãã
- IKEA PlaceïŒã¹ãŠã§ãŒãã³ïŒïŒARã䜿çšããŠãIKEAã®å®¶å ·ãèªå® ã«ä»®æ³çã«é 眮ã§ããŸããããããã¹ãã¯ãå®¶å ·ãåºãä»ã®è¡šé¢ã«æ£ç¢ºã«é 眮ããããã«äœ¿çšãããŸãã
- Sketchfab ARïŒãã©ã³ã¹ïŒïŒSketchfabã®3Dã¢ãã«ãARã§è¡šç€ºã§ããŸããããããã¹ãã¯ãã¢ãã«ãçŸå®äžçã«é 眮ããããã«äœ¿çšãããŸãã
- æ¡åŒµç»åïŒããŸããŸãªå ŽæïŒïŒå€ãã®ARã¢ããªã±ãŒã·ã§ã³ã§ã¯ãç»å远跡ãšããããã¹ããçµã¿åãããŠäœ¿çšââããä»®æ³ã³ã³ãã³ããçŸå®äžçã®ç¹å®ã®ç»åãŸãã¯ããŒã«ãŒã«åºå®ããŸãã
- WebXRã²ãŒã ïŒã°ããŒãã«ïŒïŒå€æ°ã®ã²ãŒã ãWebXRã䜿çšããŠéçºãããŠããããã®å€ãã¯ãªããžã§ã¯ãã®é 眮ãã€ã³ã¿ã©ã¯ã·ã§ã³ãããã³ããã²ãŒã·ã§ã³ã«ããããã¹ããå©çšããŠããŸãã
- ããŒãã£ã«ãã¢ãŒïŒã°ããŒãã«ïŒïŒå ŽæãçŸè¡é€šããŸãã¯ããããã£ã®æ²¡å ¥åãã¢ãŒã§ã¯ããŠãŒã¶ãŒããã²ãŒã·ã§ã³ãšä»®æ³ç°å¢å ã®ã€ã³ã¿ã©ã¯ãã£ããªèŠçŽ ã«ããããã¹ãããã䜿çšãããŸãã
çµè«
Webäžã§é åçã§çŽæçãªARããã³VRãšã¯ã¹ããªãšã³ã¹ãäœæããã«ã¯ãWebXRããããã¹ãã®çµæãšã¬ã€ãã£ã¹ãã£ã³ã°åŠçãç¿åŸããããšãäžå¯æ¬ ã§ããæ ¹æ¬çãªæŠå¿µãçè§£ãããã®ããã°æçš¿ã§èª¬æãããŠãããã¯ããã¯ãé©çšããããšã§ãä»®æ³äžçãšçŸå®äžçãã·ãŒã ã¬ã¹ã«èåãããããèªç¶ã§çŽæçãªãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ãåããé åçãªä»®æ³ç°å¢ãäœæãããã§ãããæ²¡å ¥åã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸããããã©ãŒãã³ã¹ã®ããã«ããããã¹ãã®å®è£ ãæé©åããã¯ãã¹ãã©ãããã©ãŒã ã®äºææ§ãèæ ®ããŠããã¹ãŠã®ãŠãŒã¶ãŒã«ã¹ã ãŒãºãªãšã¯ã¹ããªãšã³ã¹ãæäŸããããšãå¿ããªãã§ãã ããã WebXRãšã³ã·ã¹ãã ãé²åãç¶ããã«ã€ããŠãããããã¹ãAPIãããã«é²æ©ããæ¹è¯ãããæ²¡å ¥åWebéçºã®åµé çãªå¯èœæ§ãããã«åºããããšãæåŸ ãããŸããææ°ã®æ å ±ã«ã€ããŠã¯ãåžžã«ææ°ã®WebXR仿§ãšãã©ãŠã¶ã®ããã¥ã¡ã³ããåç §ããŠãã ããã