WebXRããããã¹ãã®å æ¬çã¬ã€ããJavaScriptã䜿ããARã§3Dãªããžã§ã¯ããçŸå®äžçã«é çœ®ã»æäœããåºæ¬ããå¿çšãŸã§ã解説ãäžçäžã®ãŠãŒã¶ãŒã«åããäœéšãæ§ç¯ããŸãããã
WebXRããããã¹ãïŒæ¡åŒµçŸå®ã«ããã3Dãªããžã§ã¯ãã®é 眮ãšã€ã³ã¿ã©ã¯ã·ã§ã³ã®ç©¶æ¥µã¬ã€ã
ã¹ããŒããã©ã³ããªãã³ã°ã«ãŒã ã«åããç°¡åãªã¿ããæäœã§ããã©ããªã¢ã«ãªä»®æ³ã®ãœãã¡ã奜ããªå Žæã«æ£ç¢ºã«é 眮ããå Žé¢ãæ³åããŠã¿ãŠãã ããããã®åšããæ©ãåãã空éã«ã©ããã£ãããããã確èªããè²ãå€ããããšããã§ããŸããããã¯SFã§ã¯ãªãããŠã§ããéããŠæäŸãããæ¡åŒµçŸå®ïŒARïŒã®åã§ããããããå¯èœã«ããã³ã¢æè¡ãWebXRããããã¹ãã§ãã
äžçäžã®éçºè ããã¶ã€ããŒãã€ãããŒã¿ãŒã«ãšã£ãŠãããããã¹ãã®çè§£ã¯ææçŸ©ãªARäœéšãè§£ãæŸã€éµãšãªããŸããããã¯ããžã¿ã«äžçãšç©çäžçãšã®éã®åºæ¬çãªæ¶ãæ©ã§ãããä»®æ³ã³ã³ãã³ãããŠãŒã¶ãŒã®çŸå®ç°å¢å ã«æ ¹ãããã€ã³ã¿ã©ã¯ãã£ãã«è¡šç€ºãããããšãå¯èœã«ããŸãããã®ã¬ã€ãã§ã¯ãWebXR Hit Test APIãæ·±ãæãäžããäžçäžã®ãŠãŒã¶ãŒã«åããŠãé åçã§äžçãèªèããARã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®ç¥èãæäŸããŸãã
WebXRããããã¹ãã®åºç€ãçè§£ãã
ã³ãŒãã«é£ã³èŸŒãåã«ãããããã¹ãã®æŠå¿µçãªåºç€ãææ¡ããããšãéèŠã§ãããã®æ žå¿ã¯ããããã€ã¹ããçŸå®äžçã«åããŠæããå Žåãã©ã®è¡šé¢ã«åœããã®ãïŒããšããåçŽãªåãã«çããããšã§ãã
ã³ã¢ã³ã³ã»ããïŒçŸå®äžçã§ã®ã¬ã€ãã£ã¹ãã£ã³ã°
ãã®ããã»ã¹ã¯ãæŠå¿µçã«ã¯åŸæ¥ã®3Dã°ã©ãã£ãã¯ã¹ã«ãããã¬ã€ãã£ã¹ãã£ã³ã°ã«äŒŒãŠããŸããã倧ããªéãããããŸããçŽç²ãªä»®æ³ã·ãŒã³ã«ã¬ã€ïŒå ç·ïŒãæãã代ããã«ãWebXRããããã¹ãã¯ãŠãŒã¶ãŒã®ããã€ã¹ããç©çäžçãžãšã¬ã€ãæããŸãã
ãã®ä»çµã¿ã¯æ¬¡ã®ãšããã§ãïŒ
- ç°å¢çè§£ïŒ ããã€ã¹ã®ã«ã¡ã©ãšã¢ãŒã·ã§ã³ã»ã³ãµãŒïŒIMU - æ £æ§èšæž¬è£ çœ®ãªã©ïŒã䜿çšããŠãåºç€ãšãªãARã·ã¹ãã ïŒAndroidã®ARCoreãiOSã®ARKitãªã©ïŒããŠãŒã¶ãŒã®åšå²ãåžžã«ã¹ãã£ã³ããåçŽåããã3Dããããæ§ç¯ããŸãããã®ãããã¯ãç¹åŸŽç¹ãæ€åºãããå¹³é¢ïŒåºãå£ãããŒãã«ããããªã©ïŒããããŠæã«ã¯ããè€éãªã¡ãã·ã¥ã§æ§æãããŸãã
- ã¬ã€ã®æå°ïŒ ã¬ã€ïŒæ¬è³ªçã«ã¯åç¹ãšæ¹åãæã€çŽç·ïŒããããåç¹ããå°åºãããŸããæãäžè¬çã«ã¯ããŠãŒã¶ãŒã®ç»é¢äžå€®ããå€åŽã«åãã£ãŠæå°ãããŸãã
- 亀ç¹ã®æ€åºïŒ ã·ã¹ãã ã¯ããã®æå°ãããã¬ã€ãæ€åºæžã¿ã®çŸå®äžçã®ãžãªã¡ããªãšäº€å·®ãããã©ããããã§ãã¯ããŸãã
- ãããããªã¶ã«ããïŒ äº€å·®ãçºçããå Žåãã·ã¹ãã ã¯ãããããªã¶ã«ãïŒãããçµæïŒããè¿ããŸãããã®çµæã¯åãªããã¯ãããããããã以äžã®ãã®ã§ããã䟡å€ã®ããããŒã¿ãç¹ã«3D空éã«ããã亀差ç¹ã®ããŒãºïŒäœçœ®ãšåãïŒãå«ãã§ããŸãããã®ããŒãºã«ãã£ãŠãä»®æ³ãªããžã§ã¯ããçŸå®äžçã®è¡šé¢ã«å®å šã«äœçœ®åããããŠé 眮ããããšãå¯èœã«ãªããŸãã
WebXR Device APIãšããããã¹ãã¢ãžã¥ãŒã«
WebXR Device APIã¯ããŠã§ãäžã§ä»®æ³çŸå®ããã³æ¡åŒµçŸå®ããã€ã¹ãžã®ã¢ã¯ã»ã¹ãæäŸããW3Cæšæºã§ããããããã¹ãAPIã¯ããã®æšæºå ã®ãªãã·ã§ã³ã¢ãžã¥ãŒã«ã§ãããç¹ã«ARåãã«èšèšãããŠããŸããããã䜿çšããã«ã¯ãWebXRã»ãã·ã§ã³ãåæåããéã«æç€ºçã«ãªã¯ãšã¹ãããå¿ èŠããããŸãã
äœæ¥ã®äžå¿ãšãªãäž»èŠãªãªããžã§ã¯ãã¯XRHitTestSourceã§ããã¢ã¯ãã£ããªXRSessionãããã®ãœãŒã¹ããªã¯ãšã¹ãããååŸããããã¬ã³ããŒãŒã«ãŒãã®åãã¬ãŒã ã§ã¯ãšãªãå®è¡ããŠææ°ã®ããããã¹ãçµæãåŸãããšãã§ããŸãã
åç §ç©ºéã®ã¿ã€ãïŒçŸå®ã«ãããã¢ã³ã«ãŒ
WebXRã®ãã¹ãŠã®åº§æšã¯ãåç §ç©ºéãå ã«ååšããããã¯3Däžçã®åç¹ïŒ0,0,0ã®ç¹ïŒãå®çŸ©ããŸããARã«ãšã£ãŠåç §ç©ºéã®éžæã¯éåžžã«éèŠã§ãã
viewerïŒ åç¹ã¯ãŠãŒã¶ãŒã®ããã€ã¹ãŸãã¯é éšã«åºå®ãããŸãããŠãŒã¶ãŒãç§»åãããšãäžçãäžç·ã«ç§»åããŸããããã¯åžžã«ãŠãŒã¶ãŒã®æ£é¢ã«ããã¹ãUIèŠçŽ ïŒãããã¢ãããã£ã¹ãã¬ã€ãªã©ïŒã«åœ¹ç«ã¡ãŸãããçŸå®äžçã«åºå®ãããã¹ããªããžã§ã¯ãã®é 眮ã«ã¯é©ããŠããŸãããlocalïŒ åç¹ã¯ã»ãã·ã§ã³éå§æã®ãŠãŒã¶ãŒã®äœçœ®ããŸãã¯ãã®è¿ãã«èšå®ãããŸãããŠãŒã¶ãŒã®éå§ç¹ã«å¯ŸããŠã¯éæ¢ããŠããŸãããçŸå®äžçã«ã¢ã³ã«ãŒããããšã¯ããŸããããã®ç©ºéã«é 眮ããããªããžã§ã¯ãã¯ãŠãŒã¶ãŒãæ©ãåã£ãŠããã®å Žã«çãŸããŸãããã»ã³ãµãŒã®èª€å·®ãèç©ãããšæéãšãšãã«ããªããïŒãºã¬ïŒããå¯èœæ§ããããŸããunboundedïŒ ãŠãŒã¶ãŒãéå§ç¹ããéåžžã«é ããŸã§æ©ãå¯èœæ§ãããã¯ãŒã«ãã¹ã±ãŒã«ã®äœéšåãã«èšèšãããŠããŸããã·ã¹ãã ã¯ãã©ããã³ã°ç²ŸåºŠãç¶æããããã«åç¹ã®äœçœ®ãèªç±ã«èª¿æŽã§ããŸããããã¯ã«ãŒã ã¹ã±ãŒã«ã®ARã«ãšã£ãŠãã°ãã°è¯ãéžæã§ããlocal-floorïŒ `local`ã«äŒŒãŠããŸãããåç¹ãç¹ã«åºã®é«ãã«èšå®ããããããå°é¢ã«ãªããžã§ã¯ããé 眮ããã®ã«éåžžã«äŸ¿å©ã§ãã
ã»ãšãã©ã®ARãªããžã§ã¯ãé
眮ã·ããªãªã§ã¯ãlocalãlocal-floorããŸãã¯unboundedã®ãããªäžçã«åºå®ããã空éã䜿çšããŠãä»®æ³ãªããžã§ã¯ããç©çç°å¢å
ã§å®å®ããŠçãŸãããã«ããŸãã
åããŠã®WebXRããããã¹ãå®è£ ïŒå®è·µçãŠã©ãŒã¯ã¹ã«ãŒ
çè«ããå®è·µã«ç§»ããŸãããã以äžã®äŸã§ã¯ãçã®WebXR APIã䜿çšããŸããå®éã®ãããžã§ã¯ãã§ã¯ãã¬ã³ããªã³ã°ãåŠçããããã«Three.jsãBabylon.jsã®ãããªã©ã€ãã©ãªã䜿çšããå¯èœæ§ãé«ãã§ãããWebXRåºæã®ããžãã¯ã¯åãã§ãã
ã¹ããã1ïŒã·ãŒã³ã®ã»ããã¢ãããšã»ãã·ã§ã³ã®ãªã¯ãšã¹ã
ãŸããARäœéšãéå§ããããã®HTMLãã¿ã³ãšãåºæ¬çãªJavaScriptã®ã»ããã¢ãããå¿
èŠã§ããæãéèŠãªéšåã¯ã'immersive-ar'ã¢ãŒãã§ã»ãã·ã§ã³ããªã¯ãšã¹ãããå¿
é æ©èœã«'hit-test'ãå«ããããšã§ãã
// HTML
<button id="ar-button">Start AR</button>
// JavaScript
const arButton = document.getElementById('ar-button');
let xrSession = null;
let xrReferenceSpace = null;
async function onARButtonClick() {
if (navigator.xr) {
try {
// Check if the immersive-ar mode is supported
const isSupported = await navigator.xr.isSessionSupported('immersive-ar');
if (isSupported) {
// Request a session with the required features
xrSession = await navigator.xr.requestSession('immersive-ar', {
requiredFeatures: ['hit-test']
});
// Set up the session, canvas, and WebGL context...
// ... (boilerplate for setting up rendering)
// Start the render loop
xrSession.requestAnimationFrame(onXRFrame);
} else {
console.log("AR not supported on this device.");
}
} catch (e) {
console.error("Failed to start AR session:", e);
}
}
}
arButton.addEventListener('click', onARButtonClick);
ã¹ããã2ïŒããããã¹ããœãŒã¹ã®ãªã¯ãšã¹ã
ã»ãã·ã§ã³ãéå§ãããããåç §ç©ºéã確ç«ããæ¬¡ã«ããããã¹ããœãŒã¹ããªã¯ãšã¹ãããå¿ èŠããããŸããããã¯éåžžãã»ãã·ã§ã³ãäœæãããçŽåŸã«è¡ãããŸãã
// Inside your session setup logic...
xrSession.addEventListener('end', onSessionEnded);
// Create a reference space. 'viewer' is needed for the hit-test request,
// but we'll get a 'local-floor' space for placing content.
xrReferenceSpace = await xrSession.requestReferenceSpace('local-floor');
const viewerSpace = await xrSession.requestReferenceSpace('viewer');
// Request the hit test source
const hitTestSource = await xrSession.requestHitTestSource({ space: viewerSpace });
// Now, we'll need to pass 'hitTestSource' to our render loop.
æ³šïŒ ããããã¹ããœãŒã¹ã¯viewer空éã䜿çšããŠãªã¯ãšã¹ãããŸããããã¯ãã¬ã€ãããã€ã¹ã®èŠç¹ããçºä¿¡ãããããšãæå³ããŸãããããããªããžã§ã¯ããé
眮ããããã«ã¯local-flooråç
§ç©ºéã䜿çšããããããã®åº§æšã¯äžçã®äžã®å®å®ããç¹ãåºæºãšããŸãã
ã¹ããã3ïŒã¬ã³ããŒã«ãŒãå ã§ããããã¹ããå®è¡ãã
éæ³ãèµ·ããã®ã¯ãã¬ã³ããªã³ã°ããããã¹ãŠã®ãã¬ãŒã ã§åŒã³åºãããonXRFrameã³ãŒã«ããã¯ã®å
éšã§ããããã§ãææ°ã®ããããã¹ãçµæãååŸããŸãã
let reticle = null; // This will be our 3D object for the visual indicator
let hitTestSource = null; // Assume this is passed from the setup step
function onXRFrame(time, frame) {
const session = frame.session;
session.requestAnimationFrame(onXRFrame);
// Get the viewer's pose
const pose = frame.getViewerPose(xrReferenceSpace);
if (!pose) return;
// If we have a hit test source, get the results
if (hitTestSource) {
const hitTestResults = frame.getHitTestResults(hitTestSource);
if (hitTestResults.length > 0) {
// We have a hit!
const hit = hitTestResults[0];
// Get the pose of the hit point
const hitPose = hit.getPose(xrReferenceSpace);
// We can now use hitPose.transform.position and hitPose.transform.orientation
// to position our visual indicator (the reticle).
if (reticle) {
reticle.visible = true;
reticle.matrix.fromArray(hitPose.transform.matrix);
}
} else {
// No hit was found for this frame
if (reticle) {
reticle.visible = false;
}
}
}
// ... rest of your rendering logic for the scene
}
ã¹ããã4ïŒã¬ãã£ã¯ã«ã§ããããã€ã³ããå¯èŠåãã
ãŠãŒã¶ãŒã¯ãã©ãã«ãªããžã§ã¯ããé 眮ã§ããããç¥ãããã«èŠèŠçãªãã£ãŒãããã¯ãå¿ èŠãšããŸãããã¬ãã£ã¯ã«ãïŒãªã³ã°ãå¹³ããªåã®ãããªå°ããª3Dãªããžã§ã¯ãïŒã¯ããã®ç®çã«æé©ã§ãã3Dã©ã€ãã©ãªïŒäŸïŒThree.jsïŒã§ãã¬ãã£ã¯ã«çšã®ã¡ãã·ã¥ãäœæããŸããåã®ã¹ãããã®ã³ãŒãã¯ããã®äœçœ®ãšå¯èŠæ§ãæŽæ°ããæ¹æ³ã瀺ããŠããŸãã
hitTestResults.length > 0ã®å Žåãã¬ãã£ã¯ã«ãå¯èŠåããhitPoseã䜿çšããŠãã®ãã©ã³ã¹ãã©ãŒã ïŒäœçœ®ãšå転ïŒãæŽæ°ããŸãã- ãããããªãå Žåã¯ãã¬ãã£ã¯ã«ãé衚瀺ã«ããŸãã
ããã«ããã峿ãã€çŽæçãªãã£ãŒãããã¯ãæäŸããããŠãŒã¶ãŒããªããžã§ã¯ãé 眮ã«é©ãã衚é¢ãèŠã€ããã®ãã¬ã€ãããŸãã
ãªããžã§ã¯ãé 眮ã®ããã®é«åºŠãªãã¯ããã¯ãšãã¹ããã©ã¯ãã£ã¹
åºæ¬çãªããããã¹ããæ©èœãããããšã¯ãã»ãã®å§ãŸãã«éããŸããããããã§ãã·ã§ãã«ã§ãŠãŒã¶ãŒãã¬ã³ããªãŒãªäœéšãåµåºããããã«ã¯ããããã®é«åºŠãªãã¯ããã¯ãæ€èšããŠãã ããã
ã¬ãã£ã¯ã«ããé 眮ãžïŒãŠãŒã¶ãŒå ¥åã®åŠç
æçµçãªç®æšã¯ãæ°žç¶çãªãªããžã§ã¯ããé
眮ããããšã§ããWebXRã¯ããã®ããã«ã·ã³ãã«ãªå
¥åã¡ã«ããºã ãæäŸããŸããããã'select'ã€ãã³ãã§ãããã®ã€ãã³ãã¯ããŠãŒã¶ãŒãäž»èŠãªã¢ã¯ã·ã§ã³ïŒéåžžã¯æºåž¯ããã€ã¹ã§ã®ç»é¢ã¿ããïŒãå®è¡ãããšãã«çºçããŸãã
xrSession.addEventListener('select', onSelect);
function onSelect() {
if (reticle && reticle.visible) {
// User has tapped the screen while the reticle is visible on a surface
// Create a new 3D object (e.g., a sunflower model)
const objectToPlace = createSunflowerModel(); // Your 3D object creation function
// Set its position and orientation to match the reticle
objectToPlace.position.copy(reticle.position);
objectToPlace.quaternion.copy(reticle.quaternion);
// Add it to your scene
scene.add(objectToPlace);
}
}
ãã®ãã¿ãŒã³ã¯åºæ¬çã§ãïŒããããã¹ãã䜿çšããŠäžæçãªããŽãŒã¹ãããŸãã¯ãã¬ãã£ã¯ã«ããªããžã§ã¯ããç¶ç¶çã«é
眮ããæ¬¡ã«selectã€ãã³ãã䜿çšããŠãã®ãªããžã§ã¯ãã®ãã©ã³ã¹ãã©ãŒã ã®æ°žç¶çãªã³ããŒãäœæããŸãã
é 眮äœéšã®å®å®å
çã®ã»ã³ãµãŒããŒã¿ã¯ãã€ãºãå€ãå Žåããããããã€ã¹ã鿢ãããŠããŠãããããã¹ãã®çµæãã€ãŸãã¬ãã£ã¯ã«ããããã«ãžãã¿ãŒïŒå°å»ã¿ã«éããïŒããããšããããŸããããã¯ãŠãŒã¶ãŒã«ãšã£ãŠäžå¿«ãªå ŽåããããŸããç°¡åãªè§£æ±ºçã¯ãç·åœ¢è£éïŒLERPïŒã®ãããªãã¯ããã¯ã䜿çšããŠã¬ãã£ã¯ã«ã®åãã«ã¹ã ãŒãžã³ã°ãé©çšããããšã§ãã
// In your onXRFrame loop, instead of setting the position directly:
const targetPosition = new THREE.Vector3();
targetPosition.setFromMatrixPosition(hitPose.transform.matrix);
// Smoothly move the reticle towards the target position
// The 0.1 value controls the smoothing speed (lower is smoother)
reticle.position.lerp(targetPosition, 0.1);
// You can do the same for orientation with slerp (Spherical Linear Interpolation)
const targetQuaternion = new THREE.Quaternion();
targetQuaternion.setFromRotationMatrix(hitPose.transform.matrix);
reticle.quaternion.slerp(targetQuaternion, 0.1);
ããããã¹ããœãŒã¹ãªãã·ã§ã³ã®çè§£
requestHitTestSourceã¡ãœããã¯ãæ¢ããŠãããã®ãçµã蟌ãããã®ãªãã·ã§ã³ãªããžã§ã¯ããåãåãããšãã§ããŸããentityTypesããããã£ã¯ç¹ã«äŸ¿å©ã§ãïŒ
entityTypes: ['plane']ïŒããã¯ãåºãããŒãã«ãå£ãªã©ã®æ€åºãããå¹³ããªè¡šé¢äžã§ã®ãããã®ã¿ãè¿ããŸããããã¯ãå®¶å ·ãä»®æ³ã¹ã¯ãªãŒã³ãªã©ã®ãªããžã§ã¯ããé 眮ããéã«æãæãŸãããªãã·ã§ã³ã§ããããšãå€ãã§ããentityTypes: ['point']ïŒããã¯ãã·ã¹ãã ã远跡ããŠããç°å¢å ã®èŠèŠçã«ç¹åŸŽçãªç¹ã§ããç¹åŸŽç¹ã§ã®ããããè¿ããŸããããã¯å¹³é¢ãããå®å®æ§ãäœãå ŽåããããŸãããããè€éã§å¹³ãã§ãªãé åãžã®é 眮ãå¯èœã«ããŸããentityTypes: ['mesh']ïŒå®éšçïŒïŒããã¯ãåçã«çæãããç°å¢ã®3Dã¡ãã·ã¥ã«å¯Ÿãããããããªã¯ãšã¹ãããŸããå©çšå¯èœãªå Žåãããã¯æã匷åãªãªãã·ã§ã³ã§ããã圢ç¶ã«é¢ä¿ãªããããã衚é¢ãžã®é 眮ãå¯èœã«ããŸãã
é 眮ããããªããžã§ã¯ããšã®ã€ã³ã¿ã©ã¯ã·ã§ã³
äžåºŠãªããžã§ã¯ããé 眮ããããšãããã¯ä»®æ³ã·ãŒã³å ã«ååšããŸãããããšã€ã³ã¿ã©ã¯ãããããã«WebXR Hit Test APIã¯ãã¯ãå¿ èŠãããŸããã代ããã«ãæšæºçãª3Dæè¡ã«æ»ããŸãã
ä»®æ³ãªããžã§ã¯ãã«å¯ŸãããŠãŒã¶ãŒã®ã¿ãããæ€åºããã«ã¯ã3Dã·ãŒã³å ã§ã¬ã€ãã£ã¹ããå®è¡ããŸãããselectãã€ãã³ãã§ã次ã®ããšãè¡ããŸãïŒ
- ã«ã¡ã©ã®äœçœ®ããå§ãŸãããã®èŠç·æ¹åãåããã¬ã€ãäœæããŸãã
- 3Dã©ã€ãã©ãªã®ã¬ã€ãã£ã¹ã¿ãŒïŒäŸïŒ`THREE.Raycaster`ïŒã䜿çšããŠããã®ã¬ã€ãšã·ãŒã³å ã®ãªããžã§ã¯ããšã®äº€å·®ããã§ãã¯ããŸãã
- é 眮ããããªããžã§ã¯ãã®ãããããšäº€å·®ãèŠã€ãã£ãå Žåãè²ãå€ããããã¢ãã¡ãŒã·ã§ã³ãåçããããåé€ããããããªã©ã®ã¢ã¯ã·ã§ã³ãããªã¬ãŒã§ããŸãã
ããã2ã€ã®æŠå¿µãåºå¥ããããšãéåžžã«éèŠã§ãïŒããããã¹ãã¯çŸå®äžçã®è¡šé¢ãèŠã€ããããã®ãã®ãã¬ã€ãã£ã¹ãã£ã³ã°ã¯ä»®æ³ã·ãŒã³å ã®ãªããžã§ã¯ããèŠã€ããããã®ãã®ã§ãã
å®äžçã§ã®å¿çšãšã°ããŒãã«ãªãŠãŒã¹ã±ãŒã¹
WebXRããããã¹ãã¯åãªãæè¡çãªå¥œå¥å¿ã®å¯Ÿè±¡ã§ã¯ãããŸãããäžçäžã®ç£æ¥ã§åŒ·åãªã¢ããªã±ãŒã·ã§ã³ãå¯èœã«ããŠããŸãã
- Eã³ããŒã¹ãšå°å£²ïŒ ã°ããŒãã«ãã©ã³ãã¯ãã©ã®åœã®ã客æ§ã«ãè³Œå ¥åã«èªå® ã§ååãèŠèŠåãããããšãã§ããŸããã¹ãŠã§ãŒãã³ã®å®¶å ·äŒç€Ÿã¯ãæ¥æ¬ã®ã客æ§ã«æ°ããããŒãã«ããã€ãã³ã°ã«ãŒã ã§ã©ã®ããã«èŠãããã確èªãããããšãã§ããŸãã
- AECïŒå»ºç¯ããšã³ãžãã¢ãªã³ã°ã建èšïŒïŒ ãã©ãžã«ã®å»ºç¯äºåæã¯ããã€ãã®ã¯ã©ã€ã¢ã³ããšWebARãªã³ã¯ãå ±æããå®éã®å»ºèšçŸå Žã§ææ¡ããã建ç©ã®1:1ã¹ã±ãŒã«ã®ä»®æ³ã¢ãã«ã®åšããæ©ãåãããšãå¯èœã«ããŸãã
- æè²ãšãã¬ãŒãã³ã°ïŒ ã€ã³ãã®å»ç§å€§åŠã¯ãåŠçã«ãŠã§ãããŒã¹ã®ARããŒã«ãæäŸããæºã®äžã«ä»®æ³ã®å¿èã眮ããŠè§£åã§ããããã«ããããšã§ãé«äŸ¡ãªããŒããŠã§ã¢ãªãã§è€éãªåŠç¿ãã¢ã¯ã»ã¹å¯èœã«ããŸãã
- ããŒã±ãã£ã³ã°ãšã¢ãŒãïŒ ã¢ãŒãã£ã¹ãããã©ã³ãã¯ããã±ãŒã·ã§ã³ããŒã¹ã®ARäœéšãäœæãããŠãŒã¶ãŒãå ¬åã«ããžã¿ã«åœ«å»ãé 眮ããããèªå® ã®è»éã«æ°ããè»çš®ãé§è»ãããŠããã®ãèŠããã§ããããã«ããŸãããããã¯äºææ§ã®ããã¹ããŒããã©ã³ãæã€èª°ã§ãã¢ã¯ã»ã¹ã§ããŸãã
WebXRããããã¹ãã®èª²é¡ãšæªæ¥
匷åã§ã¯ãããŸããããã®æè¡ã¯ãŸã é²åã®éäžã«ãããŸããéçºè ã¯ãçŸåšã®èª²é¡ãšå°æ¥ã®ãã¬ã³ããèªèããŠããã¹ãã§ãã
ããã€ã¹ãšãã©ãŠã¶ã®äºææ§
WebXRã®ãµããŒãã¯æ¡å€§ããŠããŸããããŸã æ®éçã§ã¯ãããŸãããäž»ã«Google Chromeãä»ããŠææ°ã®Androidããã€ã¹ã§å©çšå¯èœã§ããiOSã§ã®ãµããŒãã¯ããéå®çã§ãç¹å®ã®å®éšçãªãã©ãŠã¶ãå¿ èŠã«ãªãããšããããããŸããåžžã«ã°ã¬ãŒã¹ãã«ã»ãã°ã©ããŒã·ã§ã³ïŒæ®µéçæ©èœäœäžïŒã念é ã«çœ®ããŠèšèšããARé察å¿ããã€ã¹ã®ãŠãŒã¶ãŒã«ã¯ãã©ãŒã«ããã¯ãšããŠ3Dãã¥ãŒã¯ãŒäœéšãæäŸããŠãã ããã
ç°å¢çè§£ã®éç
ããããã¹ãã®å質ã¯ãç©ççãªç°å¢ã«å€§ããäŸåããŸããç¹å®ã®æ¡ä»¶äžã§ã¯ããŸãæ©èœããªãããšããããŸãïŒ
- äžååãªç §æïŒ èæãéšå±ã¯ã«ã¡ã©ãåŠçããã®ãå°é£ã§ãã
- ç¹åŸŽã®ãªã衚é¢ïŒ 倧ããªç¡å°ã®çœãå£ãå æ²¢ã®ããé»ãåºã«ã¯ããã©ããã³ã°ã«å¿ èŠãªèŠèŠçç¹åŸŽãæ¬ ããŠããŸãã
- åå°é¢ãŸãã¯éæãªè¡šé¢ïŒ é¡ãã¬ã©ã¹ã¯ãã·ã¹ãã ã®ã»ã³ãµãŒãæ··ä¹±ãããå¯èœæ§ããããŸãã
AIãšã³ã³ãã¥ãŒã¿ããžã§ã³ã®å°æ¥çãªçºå±ã¯ãããå ç¢ãªã»ãã³ãã£ãã¯ïŒæå³çïŒçè§£ã«ã€ãªããã§ããããããã€ã¹ãåãªããå¹³é¢ããèŠãã ãã§ãªãããåºãããå£ãããããŒãã«ããšããŠèªèããããã€ã³ããªãžã§ã³ããªã€ã³ã¿ã©ã¯ã·ã§ã³ãå¯èœã«ããŸãã
Depth APIãšMesh APIã®å°é
ããããã¹ãã®æªæ¥ã¯ãããé«åºŠãªç°å¢ããŒã¿ã«ãããŸããæ°ãã«åºçŸããŠããWebXR APIã¯ãããã驿°ããããšããŠããŸãïŒ
- WebXR Depth Sensing APIïŒ ã«ã¡ã©ãããã¯ã»ã«ããšã®æ·±åºŠæ å ±ãæäŸããã¯ããã«è©³çްãªçŸå®äžçã®ãžãªã¡ããªæ€åºãå¯èœã«ããŸããããã«ãããä»®æ³ãªããžã§ã¯ããçŸå®äžçã®ãªããžã§ã¯ãã«ãã£ãŠæ£ãããªã¯ã«ãŒãžã§ã³ãããïŒé ãããïŒããã«ãªããŸãïŒäŸïŒä»®æ³ãã£ã©ã¯ã¿ãŒãçŸå®ã®ãœãã¡ã®åŸããæ©ãïŒã
- Real-World Geometry (Mesh API)ïŒ ãã®APIã¯ãç°å¢ã®åçãªãªã¢ã«ã¿ã€ã 3Dã¡ãã·ã¥ãæäŸããŸãããã®ã¡ãã·ã¥ã«å¯ŸããŠããããã¹ããè¡ãããšã§ãæ¬ã®å±±ãããããã¡ãã®æ¯åžãŸã§ãã©ããªã«è€éãªè¡šé¢ã«ãå®ç§ãªé 眮ãå¯èœã«ãªããŸãã
çµè«ïŒäžçãšäžçã®éã«æ©ãæ¶ãã
WebXRããããã¹ãã¯åãªãAPIã§ã¯ãããŸãããããã¯ãç§ãã¡ã®ããžã¿ã«ãªåµé ç©ãç©ççãªçŸå®ã«æ ¹ä»ãããããšãå¯èœã«ããåºæ¬çãªã¡ã«ããºã ã§ãããœãŒã¹ã®ãªã¯ãšã¹ãæ¹æ³ãã¬ã³ããŒãŒã«ãŒãã§ã®çµæã®åŠçæ¹æ³ããŠãŒã¶ãŒå ¥åã®åŠçæ¹æ³ãçè§£ããããšã§ããŠã§ããã©ãŠã¶ãéããŠå·šå€§ãªäžçäžã®ãªãŒãã£ãšã³ã¹ãã¢ã¯ã»ã¹ã§ãããçŽæçã§åŒ·åãªARäœéšãæ§ç¯ã§ããŸãã
åçŽãªãªããžã§ã¯ãé 眮ããè€éãªã€ã³ã¿ã©ã¯ãã£ãã¢ããªã±ãŒã·ã§ã³ãŸã§ãããããã¹ãã®ç¿åŸã¯ã€ããŒã·ããŠã§ãã«åå ¥ãããã¹ãŠã®éçºè ã«ãšã£ãŠå¿ é ã®ã¹ãã«ã§ããæè¡ãããåªããç°å¢ã»ã³ã·ã³ã°ãšå¹ åºãããã€ã¹ãµããŒãã§é²åãç¶ããã«ã€ããŠãç©çäžçãšããžã¿ã«äžçã®å¢çç·ã¯ãŸããŸãææ§ã«ãªããWebXRã¯ãã®å€é©ã®æåç·ã«ç«ã€ããšã«ãªãã§ãããã