WebXRã®ããã¹ãããã¡è§£å床ã®ç®¡çãã¢ãŒãã£ãã¡ã¯ãã®ãã£ã«ã¿ãªã³ã°ãå ç¢ãªARãªã¯ã«ãŒãžã§ã³ãšã€ã³ã¿ã©ã¯ã·ã§ã³ã®ããã®å質管çãå®è£ ããæ¹æ³ãéçºè åãã«è©³èª¬ããã¬ã€ãã
WebXR深床ã®ç¿åŸïŒããã¹ãããã¡ã®è§£å床ãšå質管çãžã®æ·±æã
æ¡åŒµçŸå®ïŒARïŒã¯ãµã€ãšã³ã¹ãã£ã¯ã·ã§ã³ã®é åãè¶ ããç§ãã¡ãããžã¿ã«æ å ±ãšå¯Ÿè©±ããæ¹æ³ãåæ§ç¯ãããå ·äœçã§åŒ·åãªããŒã«ãšãªããŸãããARã®éæ³ã¯ãä»®æ³ãšçŸå®ãã·ãŒã ã¬ã¹ã«èåãããèœåã«ãããŸããä»®æ³ãã£ã©ã¯ã¿ãŒããªãã³ã°ã®å®¶å ·ãé¿ããªããåãåããããžã¿ã«æž¬å®ããŒã«ãçŸå®äžçã®ãªããžã§ã¯ããæ£ç¢ºã«æž¬å®ããä»®æ³ã¢ãŒãäœåãçŸå®ã®æ±ã®èåŸã«æ£ããé ããâãããã®äœéšã¯ãããéèŠãªæè¡ã«äŸåããŠããŸããããã¯ãªã¢ã«ã¿ã€ã ã®ç°å¢çè§£ã§ãããŠã§ãããŒã¹ARã«ããããã®çè§£ã®äžå¿ã«ããã®ããWebXR Depth APIã§ãã
Depth APIã¯ãããã€ã¹ã®ã«ã¡ã©ããèŠãçŸå®äžçã®ãžãªã¡ããªã®ãã¬ãŒã ããšã®æšå®å€ãéçºè ã«æäŸããŸããäžè¬ã«æ·±åºŠããããšããŠç¥ããããã®ããŒã¿ã¯ããªã¯ã«ãŒãžã§ã³ããªã¢ã«ãªç©çæŒç®ãç°å¢ã¡ãã·ã³ã°ãšãã£ãé«åºŠãªæ©èœãå®çŸããããã®éµãšãªããŸãããããããã®æ·±åºŠããŒã¿ãžã®ã¢ã¯ã»ã¹ã¯æåã®ã¹ãããã«éããŸãããçã®æ·±åºŠæ å ±ã¯ãã°ãã°ãã€ãºãå€ããäžè²«æ§ããªããã¡ã€ã³ã«ã¡ã©ã®æ åãããè§£å床ãäœããã®ã§ããé©åãªåŠçãè¡ããªããšããªã¯ã«ãŒãžã§ã³ã®ã¡ãã€ããäžå®å®ãªç©çæŒç®ããããŠæ²¡å ¥æã®ããå¹»æ³ã®å šäœçãªåŽ©å£ã«ã€ãªããå¯èœæ§ããããŸãã
ãã®å æ¬çãªã¬ã€ãã¯ãåºæ¬çãªARãè¶ ããçã«å ç¢ã§ä¿¡é Œæ§ã®é«ãäœéšã®é åãžãšé²ã¿ããWebXRéçºè ã®ããã®ãã®ã§ããç§ãã¡ã¯ããã¹ãããã¡ã®è§£ååºŠã®æŠå¿µãåæãããã®å質ãäœäžãããèŠå ãæ¢ããå質管çããã£ã«ã¿ãªã³ã°ãæ€èšŒã®ããã®å®è·µçãªãã¯ããã¯ã®ããŒã«ããã¯ã¹ãæäŸããŸãããããã®æŠå¿µãç¿åŸããããšã§ããã€ãºã®å€ãçããŒã¿ããæ¬¡äžä»£ARã¢ããªã±ãŒã·ã§ã³ã®ããã®å®å®çã§ä¿¡é Œæ§ã®é«ãåºç€ãžãšå€ããããšãã§ããŸãã
第1ç« ïŒWebXR Depth APIã®åºç€
深床ãããã®å質ã管çããåã«ããŸããããäœã§ãããã©ã®ããã«ã¢ã¯ã»ã¹ããã®ããçè§£ããå¿ èŠããããŸããWebXR Depth Sensing APIã¯ãWebXR Device APIå ã®ã¢ãžã¥ãŒã«ã§ãããããã€ã¹ã®ã»ã³ãµãŒã«ãã£ãŠãã£ããã£ãããæ·±åºŠæ å ±ãå ¬éããŸãã
深床ããããšã¯äœãïŒ
åçãæ®ãããšãæ³åããŠã¿ãŠãã ãããããããåãã¯ã»ã«ã«è²æ å ±ãä¿åãã代ããã«ãã«ã¡ã©ãããã®ãã¯ã»ã«ã衚ããªããžã§ã¯ããŸã§ã®è·é¢ãä¿åããŸãããããæ¬è³ªçã«æ·±åºŠãããã§ããããã¯éåžžã°ã¬ãŒã¹ã±ãŒã«ã®2Dç»åã§ããã¯ã»ã«ã®èŒåºŠãè·é¢ã«å¯Ÿå¿ããŸããæãããã¯ã»ã«ã¯ããè¿ããªããžã§ã¯ãã衚ããæããã¯ã»ã«ã¯ããé ããªããžã§ã¯ãã衚ããããããŸããïŒãããã¯ãèŠèŠåã®æ¹æ³ã«ãã£ãŠã¯ãã®éããããŸãïŒã
ãã®ããŒã¿ã¯ã`XRDepthInformation.texture`ãšããŠãã¯ã¹ãã£ãšããŠWebGLã³ã³ããã¹ãã«æäŸãããŸããããã«ãããã·ã§ãŒããŒå ã§GPUäžã§çŽæ¥ãéåžžã«å¹ççãªãã¯ã»ã«ããšã®æ·±åºŠèšç®ãå®è¡ã§ããŸããããã¯ãªã¢ã«ã¿ã€ã ARã«ãšã£ãŠéèŠãªããã©ãŒãã³ã¹äžã®èæ ®äºé ã§ãã
WebXRãæ·±åºŠæ å ±ãæäŸããæ¹æ³
APIã䜿çšããã«ã¯ããŸãWebXRã»ãã·ã§ã³ãåæåããéã«`depth-sensing`æ©èœããªã¯ãšã¹ãããå¿ èŠããããŸãã
const session = await navigator.xr.requestSession('immersive-ar', { requiredFeatures: ['depth-sensing'] });
ããŒã¿åœ¢åŒãäœ¿çšæ¹æ³ã«é¢ããèšå®ãæå®ã§ããŸããããã«ã€ããŠã¯åŸã»ã©ããã©ãŒãã³ã¹ã®ã»ã¯ã·ã§ã³ã§è©³ãã説æããŸããã»ãã·ã§ã³ãã¢ã¯ãã£ãã«ãªããšã`requestAnimationFrame`ã«ãŒãå ã§ãWebGLã¬ã€ã€ãŒããææ°ã®æ·±åºŠæ å ±ãååŸããŸãã
const depthInfo = xrWebView.getDepthInformation(xrFrame.getViewerPose(xrReferenceSpace));
`depthInfo`ãå©çšå¯èœãªå Žåãããã«ã¯ããã€ãã®éèŠãªæ å ±ãå«ãŸããŠããŸãã
- texture: çã®æ·±åºŠå€ãå«ã`WebGLTexture`ã
- normDepthFromViewMatrix: ãã¥ãŒç©ºé座æšãæ£èŠåãããæ·±åºŠãã¯ã¹ãã£åº§æšã«å€æããããã®è¡åã
- rawValueToMeters: ãã¯ã¹ãã£ããã®åäœã®ãªãçã®å€ãã¡ãŒãã«ã«å€æããããã®ã¹ã±ãŒãªã³ã°ä¿æ°ãããã¯æ£ç¢ºãªå®äžç枬å®ã«äžå¯æ¬ ã§ãã
ãã®ããŒã¿ãçæããåºç€æè¡ã¯ããã€ã¹ã«ãã£ãŠç°ãªããŸããäžéšã¯é£è¡æéïŒTime-of-Flight, ToFïŒãæ§é åå ã®ãããªã¢ã¯ãã£ãã»ã³ãµãŒã䜿çšããèµ€å€å ãæå°ããŠãã®æ»ããæž¬å®ããŸãããã®ä»ã¯ãã¹ãã¬ãªã¹ã³ããã¯ã«ã¡ã©ã®ãããªããã·ããªæ¹æ³ã䜿çšãã2ã€ã®ç»åéã®äžèŽãèŠã€ããŠæ·±åºŠãèšç®ããŸããéçºè ãšããŠããŒããŠã§ã¢ãå¶åŸ¡ããããšã¯ã§ããŸãããããã®éçãçè§£ããããšã¯ããããçæããããŒã¿ã管çããäžã§éèŠã§ãã
第2ç« ïŒããã¹ãããã¡è§£å床ã®2ã€ã®åŽé¢
éçºè ããè§£å床ããšèããšãç»åã®å¹ ãšé«ããæãæµ®ãã¹ãããšãå€ãã§ããããæ·±åºŠãããã«ãšã£ãŠãããã¯è©±ã®ååã«éããŸãããæ·±åºŠè§£å床ã¯2ã€ã®éšåãããªãæŠå¿µã§ãããã©ã¡ããå質ã«ãšã£ãŠéèŠã§ãã
空éè§£å床ïŒãäœãããã©ãã«ã
空éè§£å床ã¯ã深床ãã¯ã¹ãã£ã®æ¬¡å ãäŸãã°320x240ã640x480ãã¯ã»ã«ãæããŸããããã¯å€ãã®å Žåãããã€ã¹ã®ã«ã©ãŒã«ã¡ã©ã®è§£å床ïŒ1920x1080以äžã«ãªãããšãããïŒãããå€§å¹ ã«äœãã§ãããã®äžäžèŽãARã¢ãŒãã£ãã¡ã¯ãã®äž»ãªåå ã§ãã
- ãã£ããŒã«ãžã®åœ±é¿: äœã空éè§£å床ã¯ãåæ·±åºŠãã¯ã»ã«ãçŸå®äžçã®ããåºãé åãã«ããŒããããšãæå³ããŸããããã«ããã现ãããã£ããŒã«ãæããããšãäžå¯èœã«ãªããŸããããŒãã«ã®ç«¯ã¯ãããã¯ç¶ã«èŠãã现ãã©ã³ãã®æ±ã¯å®å šã«æ¶ããŠããŸããè¿ãã«ãããªããžã§ã¯ãéã®åºå¥ãææ§ã«ãªããŸãã
- ãªã¯ã«ãŒãžã§ã³ãžã®åœ±é¿: ãã®åé¡ãæãé¡èã«çŸããã®ãããã§ããä»®æ³ãªããžã§ã¯ããçŸå®äžçã®ãªããžã§ã¯ãã®äžéšã«é ãããšãããªã¯ã«ãŒãžã§ã³ã®å¢çã«æ²¿ã£ãäœè§£å床ã®ãéæ®µç¶ãã®ã¢ãŒãã£ãã¡ã¯ããç®ç«ã¡ãæ²¡å ¥æãæãªããŸãã
ãããäœè§£å床ã®åçã®ããã«èããŠã¿ãŠãã ããã倧ãŸããªåœ¢ã¯ããããŸããã现ãããã£ããŒã«ãé®®æãªãšããžã¯ãã¹ãŠå€±ãããŠããŸããéçºè ã«ãšã£ãŠã®èª²é¡ã¯ããã®äœè§£å床ããŒã¿ãè³¢ããã¢ãããµã³ããªã³ã°ãããããæ±ã£ããããŠãé«è§£å床ã®çµæãäœæããããšã§ãã
ãããæ·±åºŠïŒç²ŸåºŠïŒïŒãã©ããããé ããã
ãããæ·±åºŠããŸãã¯ç²ŸåºŠã¯ãã©ãã ãå€ãã®ç°ãªãè·é¢ã®æ®µéã衚çŸã§ããããæ±ºå®ããŸããããã¯æ·±åºŠãããã®åãã¯ã»ã«å€ã®æ°å€çãªç²ŸåºŠã§ããWebXR APIã¯ã16ããã笊å·ãªãæŽæ°ïŒ`ushort`ïŒã32ãããæµ®åå°æ°ç¹æ°ïŒ`float`ïŒãªã©ãããŸããŸãªåœ¢åŒã§ããŒã¿ãæäŸããå ŽåããããŸãã
- 8ãããæ·±åºŠïŒ256段éïŒ: 8ããã圢åŒã§ã¯256ã®é¢æ£çãªè·é¢ãã衚çŸã§ããŸããã5ã¡ãŒãã«ã®ç¯å²ã§ã¯ãåã¹ããããã»ãŒ2ã»ã³ãã¡ãŒãã«é¢ããŠããããšãæå³ããŸãã1.00mãš1.01mã«ãããªããžã§ã¯ãã¯åãæ·±åºŠå€ãå²ãåœãŠãããå¯èœæ§ãããããæ·±åºŠã®éååããŸãã¯ãã³ãã£ã³ã°ãšããŠç¥ãããçŸè±¡ã«ã€ãªãããŸãã
- 16ãããæ·±åºŠïŒ65,536段éïŒ: ããã¯å€§å¹ ãªæ¹åã§ãããäžè¬çãªåœ¢åŒã§ããããæ»ããã§æ£ç¢ºãªè·é¢è¡šçŸãæäŸããéååã¢ãŒãã£ãã¡ã¯ããæžããããã埮åŠãªæ·±åºŠã®å€åãæããããšãã§ããŸãã
- 32ãããæµ®åå°æ°ç¹æ°: æé«ã®ç²ŸåºŠãæäŸããç§åŠçãŸãã¯æž¬å®çšéã«çæ³çã§ããæŽæ°åœ¢åŒã®åºå®ã¹ãããã®åé¡ãåé¿ããŸãããããã©ãŒãã³ã¹ãšã¡ã¢ãªã®ã³ã¹ããé«ããªããŸãã
äœããããæ·±åºŠã¯ãZãã¡ã€ãã£ã³ã°ããåŒãèµ·ããå¯èœæ§ãããããããã«ç°ãªã深床ã«ãã2ã€ã®ãµãŒãã§ã¹ãåé¢ã«ã¬ã³ããªã³ã°ãããããã«ç«¶åããã¡ãã€ã广ãåŒãèµ·ãããŸãããŸããæ»ãããªãµãŒãã§ã¹ã段ã çãçžæš¡æ§ã«èŠããåå ã«ããªããããã¯ä»®æ³ã®ããŒã«ãæ»ãããªæé¢ã§ã¯ãªãäžé£ã®é段ã転ããèœã¡ãããã«èŠããç©çã·ãã¥ã¬ãŒã·ã§ã³ã§ç¹ã«é¡èã§ãã
第3ç« ïŒçŸå®äžç vs çæ³ã®æ·±åºŠãããïŒå質ã«åœ±é¿ãäžããèŠå
å®ç§ãªäžçã§ã¯ããã¹ãŠã®æ·±åºŠãããã¯é®®æã§é«è§£å床ã§ãããçŸå®ãå®å šã«æ£ç¢ºã«è¡šçŸããŠããŸãããããå®éã«ã¯ã深床ããŒã¿ã¯ä¹±éã§ãããŸããŸãªç°å¢çããã³ããŒããŠã§ã¢ããŒã¹ã®åé¡ã®åœ±é¿ãåããããã§ãã
ããŒããŠã§ã¢ãžã®äŸå
çããŒã¿ã®å質ã¯ãåºæ¬çã«ããã€ã¹ã®ããŒããŠã§ã¢ã«ãã£ãŠäžéãæ±ºããããŸããã»ã³ãµãŒã倿Žããããšã¯ã§ããŸãããããã®å žåçãªåŒ±ç¹ãèªèããããšã¯ãå ç¢ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«éèŠã§ãã
- ã»ã³ãµãŒã®çš®é¡: å€ãã®ãã€ãšã³ãã¢ãã€ã«ããã€ã¹ã§äžè¬çãªé£è¡æéïŒToFïŒã»ã³ãµãŒã¯äžè¬çã«åªããŠããŸãããåšå²ã®èµ€å€å ïŒäŸãã°ãæãã倪éœå ïŒã®åœ±é¿ãåããããšããããŸããã¹ãã¬ãªã¹ã³ããã¯ã·ã¹ãã ã¯ãçã£çœãªå£ã®ãããªãã¯ã¹ãã£ã®ãªã衚é¢ã§èŠåŽããå¯èœæ§ãããã2ã€ã®ã«ã¡ã©ãã¥ãŒéã§äžèŽãããã¹ãç¹åŸŽããªãããã§ãã
- ããã€ã¹ã®é»åãããã¡ã€ã«: ããããªãŒãç¯çŽããããã«ãããã€ã¹ã¯æå³çã«äœè§£å床ãŸãã¯ãã€ãºã®å€ã深床ããããæäŸããå ŽåããããŸããäžéšã®ããã€ã¹ã§ã¯ãç°ãªãã»ã³ã·ã³ã°ã¢ãŒããåãæ¿ããããšãããããå質ã®é¡èãªå€åãåŒãèµ·ãããŸãã
ç°å¢çãªåŠšå®³èŠå
ãŠãŒã¶ãŒãããç°å¢ã¯ã深床ããŒã¿ã®å質ã«å€§ããªåœ±é¿ãäžããŸããããªãã®ARã¢ããªã±ãŒã·ã§ã³ã¯ããããã®äžè¬çãªèª²é¡ã«å¯ŸããŠèæ§ãæã€å¿ èŠããããŸãã
- å°é£ãªè¡šé¢ç¹æ§:
- åå°é¢: é¡ã磚ãããéå±ã¯ããŒã¿ã«ã®ããã«æ©èœãã衚é¢èªäœã®æ·±åºŠã§ã¯ãªããåå°ãããã·ãŒã³ã®æ·±åºŠã瀺ããŸããããã«ãããæ·±åºŠãããã«å¥åŠã§äžæ£ç¢ºãªãžãªã¡ããªãäœæãããå¯èœæ§ããããŸãã
- éæãªè¡šé¢: ã¬ã©ã¹ãéæãªãã©ã¹ããã¯ã¯æ·±åºŠã»ã³ãµãŒã«ã¯èŠããªãããšãå€ãã倧ããªç©Žãããã®åŸãã«ãããã®ã®äžæ£ç¢ºãªæ·±åºŠæž¬å®ã«ã€ãªãããŸãã
- æãããŸãã¯å ãåžåãã衚é¢: éåžžã«æãããããªè¡šé¢ïŒé»ããã«ããããªã©ïŒã¯ãã¢ã¯ãã£ãã»ã³ãµãŒããã®èµ€å€å ãåžåããããŒã¿ãæ¬ èœïŒç©ŽïŒããçµæãšãªããŸãã
- ç §ææ¡ä»¶: 匷ã倪éœå ã¯ToFã»ã³ãµãŒãå§åãã倧ããªãã€ãºãçºçãããå¯èœæ§ããããŸããéã«ãéåžžã«æãç §ææ¡ä»¶ã¯ãå¯èŠçãªç¹åŸŽã«äŸåããããã·ãã¹ãã¬ãªã·ã¹ãã ã«ãšã£ãŠå°é£ãªå ŽåããããŸãã
- è·é¢ãšç¯å²: ãã¹ãŠã®æ·±åºŠã»ã³ãµãŒã«ã¯æé©ãªåäœç¯å²ããããŸããè¿ããããªããžã§ã¯ãã¯çŠç¹ãåããªãå¯èœæ§ããããé ãã®ãªããžã§ã¯ãã«å¯Ÿãã粟床ã¯å€§å¹ ã«äœäžããŸããã»ãšãã©ã®æ¶è²»è åãã»ã³ãµãŒã¯ãçŽ5ã8ã¡ãŒãã«ãŸã§ããä¿¡é Œã§ããŸããã
- ã¢ãŒã·ã§ã³ãã©ãŒ: ããã€ã¹ãŸãã¯ã·ãŒã³å ã®ãªããžã§ã¯ãã®æ¥éãªåãã¯ã深床ãããã«ã¢ãŒã·ã§ã³ãã©ãŒãåŒãèµ·ããããšããžãã«ããã ããäžæ£ç¢ºãªèªã¿åãã«ã€ãªãã£ããããå¯èœæ§ããããŸãã
第4ç« ïŒéçºè ã®ããŒã«ããã¯ã¹ïŒå質管çã®ããã®å®è·µçãã¯ããã¯
åé¡ç¹ãçè§£ãããšããã§ã解決çã«çŠç¹ãåœãŠãŸããããç®æšã¯å®ç§ãªæ·±åºŠããããéæããããšã§ã¯ãããŸããâããã¯ãã°ãã°äžå¯èœã§ããç®æšã¯ãçã®ãã€ãºã®å€ãããŒã¿ããã¢ããªã±ãŒã·ã§ã³ã®ããŒãºã«ãšã£ãŠäžè²«æ§ããããå®å®ããŠããŠãååã«è¯ããã®ã«åŠçããããšã§ãã以äžã®ãã¹ãŠã®ãã¯ããã¯ã¯ããªã¢ã«ã¿ã€ã ããã©ãŒãã³ã¹ã®ããã«WebGLã·ã§ãŒããŒã§å®è£ ããå¿ èŠããããŸãã
ãã¯ããã¯1ïŒæéçãã£ã«ã¿ãªã³ã°ïŒæéçµéã«ããå¹³æ»åïŒ
ãã¬ãŒã ãããã¬ãŒã ãžã®æ·±åºŠããŒã¿ã¯éåžžã«ããžãã¿ãŒããå€ããåã ã®ãã¯ã»ã«ããã®å€ãæ¥éã«å€åãããããšããããŸããæéçãã£ã«ã¿ãªã³ã°ã¯ãçŸåšã®ãã¬ãŒã ã®æ·±åºŠããŒã¿ãåã®ãã¬ãŒã ã®ããŒã¿ãšãã¬ã³ãããããšã§ãããæ»ããã«ããŸãã
ã·ã³ãã«ã§å¹æçãªæ¹æ³ã¯ãææ°ç§»åå¹³åïŒEMAïŒã§ããã·ã§ãŒããŒã§ã¯ãåã®ãã¬ãŒã ããå¹³æ»åãããæ·±åºŠãä¿åãããå±¥æŽããã¯ã¹ãã£ãç¶æããŸãã
æŠå¿µçãªã·ã§ãŒããŒããžãã¯:
float smoothing_factor = 0.6; // 0ãã1ã®éã®å€ãé«ãã»ã©å¹³æ»åã匷ããªãã
vec2 tex_coord = ...; // çŸåšã®ãã¯ã»ã«ã®ãã¯ã¹ãã£åº§æš
float current_depth = texture2D(new_depth_map, tex_coord).r;
float previous_depth = texture2D(history_depth_map, tex_coord).r;
// çŸåšã®æ·±åºŠãæå¹ãªå ŽåïŒ0ã§ãªãå ŽåïŒã®ã¿æŽæ°
if (current_depth > 0.0) {
float smoothed_depth = mix(current_depth, previous_depth, smoothing_factor);
// 次ã®ãã¬ãŒã ã®ããã«ãå¹³æ»åãããæ·±åºŠãæ°ããå±¥æŽãã¯ã¹ãã£ã«æžã蟌ã
} else {
// çŸåšã®ããŒã¿ãç¡å¹ãªå Žåã¯ãå€ãããŒã¿ããã®ãŸãŸåŒãç¶ã
// åã®æ·±åºŠãæ°ããå±¥æŽãã¯ã¹ãã£ã«æžã蟌ã
}
é·æ: é«åšæ³¢ãã€ãºãã¡ãã€ããæžããã®ã«éåžžã«åªããŠããŸãããªã¯ã«ãŒãžã§ã³ãç©çã€ã³ã¿ã©ã¯ã·ã§ã³ãã¯ããã«å®å®ããŠæããããŸãã
çæ: ç¹ã«éãåããªããžã§ã¯ãã§ãããããªé å»¶ãããŽãŒã¹ãã£ã³ã°ã广ãå°å ¥ããŸãã`smoothing_factor`ã¯ãå®å®æ§ãšå¿çæ§ã®ãã©ã³ã¹ãåãããã«èª¿æŽããå¿ èŠããããŸãã
ãã¯ããã¯2ïŒç©ºéçãã£ã«ã¿ãªã³ã°ïŒé£æ¥ãã¯ã»ã«ã«ããå¹³æ»åïŒ
空éçãã£ã«ã¿ãªã³ã°ã¯ããã¯ã»ã«ã®å€ããã®é£æ¥ãã¯ã»ã«ã®å€ã«åºã¥ããŠå€æŽããããšãå«ã¿ãŸããããã¯ãå€ç«ãã誀ã£ããã¯ã»ã«ãä¿®æ£ããå°ããªå¹åžãæ»ããã«ããã®ã«æé©ã§ãã
- ã¬ãŠã·ã¢ã³ãã©ãŒ: åçŽãªãŒããã¯ãã€ãºãæžããããšãã§ããŸãããããŒãã«ã®è§ãäžžããªã£ããããªã¯ã«ãŒãžã§ã³ã®å¢çããŒãããããããªã©ãéèŠãªã·ã£ãŒããªãšããžãæãããããŠããŸããŸãããã®ãŠãŒã¹ã±ãŒã¹ã«ã¯äžè¬çã«åŒ·ãããŸãã
- ãã€ã©ãã©ã«ãã£ã«ã¿ãŒ: ããã¯ãšããžãä¿æããå¹³æ»åãã£ã«ã¿ãŒã§ãã飿¥ãã¯ã»ã«ãå¹³ååããããšã§æ©èœããŸãããäžå¿ãã¯ã»ã«ãšäŒŒã深床å€ãæã€é£æ¥ãã¯ã»ã«ã«ããå€ãã®éã¿ãäžããŸããããã¯ãå¹³ããªå£ã¯æ»ããã«ããŸãããæ·±åºŠã®äžé£ç¶æ§ïŒæºã®ç«¯ãªã©ïŒãè¶ããŠãã¯ã»ã«ãå¹³ååããªãããšãæå³ããŸããããã¯æ·±åºŠãããã«ã¯ããã«é©ããŠããŸãããåçŽãªãŒãããããèšç®ã³ã¹ããé«ããªããŸãã
ãã¯ããã¯3ïŒç©Žåããšã€ã³ãã€ã³ãã£ã³ã°
å€ãã®å Žåãæ·±åºŠãããã«ã¯ã»ã³ãµãŒãèªã¿åãã«å€±æããã穎ãïŒå€ã0ã®ãã¯ã»ã«ïŒãå«ãŸããŸãããããã®ç©Žã¯ãä»®æ³ãªããžã§ã¯ããäºæããçŸãããæ¶ãããããåå ãšãªããŸããç°¡åãªç©Žåããã¯ããã¯ã§ããã軜æžã§ããŸãã
æŠå¿µçãªã·ã§ãŒããŒããžãã¯:
vec2 tex_coord = ...;
float center_depth = texture2D(depth_map, tex_coord).r;
if (center_depth == 0.0) {
// ããã穎ã®å Žåã飿¥ãã¯ã»ã«ããµã³ããªã³ã°ããŠæå¹ãªãã®ãå¹³åãã
float total_depth = 0.0;
float valid_samples = 0.0;
// ... 3x3ãŸãã¯5x5ã®é£æ¥ã°ãªãããã«ãŒã ...
// if (neighbor_depth > 0.0) { total_depth += neighbor_depth; valid_samples++; }
if (valid_samples > 0.0) {
center_depth = total_depth / valid_samples;
}
}
// ïŒåããããå¯èœæ§ã®ããïŒäžå¿æ·±åºŠå€ã䜿çšãã
ããé«åºŠãªãã¯ããã¯ã«ã¯ã穎ã®ç«¯ããå åŽã«åãã£ãŠæ·±åºŠå€ãäŒæãããæ¹æ³ããããŸãããåçŽãªé£æ¥å¹³åã§ãããå®å®æ§ãå€§å¹ ã«åäžãããããšãã§ããŸãã
ãã¯ããã¯4ïŒè§£å床ã®ã¢ãããµã³ããªã³ã°
åè¿°ã®éããæ·±åºŠãããã¯éåžžãã«ã©ãŒç»åãããã¯ããã«è§£å床ãäœãã§ããæ£ç¢ºãªãã¯ã»ã«ããšã®ãªã¯ã«ãŒãžã§ã³ãå®è¡ããã«ã¯ãé«è§£ååºŠã®æ·±åºŠããããçæããå¿ èŠããããŸãã
- ãã€ãªãã¢è£é: ãããæãç°¡åãªæ¹æ³ã§ããã·ã§ãŒããŒã§äœè§£ååºŠã®æ·±åºŠãã¯ã¹ãã£ããµã³ããªã³ã°ããéãGPUã®ããŒããŠã§ã¢ãµã³ãã©ãŒãæãè¿ã4ã€ã®æ·±åºŠãã¯ã»ã«ãèªåçã«ãã¬ã³ãã§ããŸããããã¯é«éã§ãããéåžžã«ãŒããããšããžã«ãªããŸãã
- ãšããžãæèããã¢ãããµã³ããªã³ã°: ããé«åºŠãªã¢ãããŒãã¯ãé«è§£å床ã®ã«ã©ãŒç»åãã¬ã€ããšããŠäœ¿çšããŸãããã®è«çã¯ãã«ã©ãŒç»åã«ã·ã£ãŒããªãšããžãããå ŽåïŒäŸãã°ãæããå£ã«å¯Ÿããæãæ€ åã®ãšããžïŒã深床ãããã«ãã·ã£ãŒããªãšããžãããã¹ãã ãšããããšã§ããããã«ããããªããžã§ã¯ãã®å¢çãè¶ããŠãŒãããã®ãé²ããŸãããŒãããå®è£ ããã®ã¯è€éã§ãããäžå¿çãªã¢ã€ãã¢ã¯ã空éçãªè·é¢ãšé«è§£å床ã«ã¡ã©ãã¯ã¹ãã£ã®è²é¡äŒŒæ§ã®äž¡æ¹ã«åºã¥ããŠãã£ã«ã¿ãŒã®éã¿ã倿Žããããžã§ã€ã³ããã€ã©ãã©ã«ã¢ãããµã³ãã©ãŒã®ãããªãã¯ããã¯ã䜿çšããããšã§ãã
ãã¯ããã¯5ïŒãããã°ãšå¯èŠå
èŠããªããã®ã¯ä¿®æ£ã§ããŸãããå質管çããŒã«ããã¯ã¹ã®äžã§æã匷åãªããŒã«ã®1ã€ã¯ã深床ããããçŽæ¥å¯èŠåããèœåã§ããæ·±åºŠãã¯ã¹ãã£ãç»é¢äžã®åè§åœ¢ã«ã¬ã³ããªã³ã°ã§ããŸããçã®æ·±åºŠå€ã¯å¯èŠç¯å²ã«ãªãããããã©ã°ã¡ã³ãã·ã§ãŒããŒã§æ£èŠåããå¿ èŠããããŸãã
æŠå¿µçãªæ£èŠåã·ã§ãŒããŒããžãã¯:
float raw_depth = texture2D(depth_map, tex_coord).r;
float depth_in_meters = raw_depth * rawValueToMeters;
// å¯èŠåã®ããã«0-1ã®ç¯å²ã«æ£èŠåãããäŸïŒæå€§5ã¡ãŒãã«ã®ç¯å²ã®å Žå
float max_viz_range = 5.0;
float normalized_color = clamp(depth_in_meters / max_viz_range, 0.0, 1.0);
gl_FragColor = vec4(normalized_color, normalized_color, normalized_color, 1.0);
çããã£ã«ã¿ãªã³ã°æžã¿ãã¢ãããµã³ããªã³ã°æžã¿ã®æ·±åºŠãããã䞊ã¹ãŠè¡šç€ºããããšã§ããã£ã«ã¿ãªã³ã°ãã©ã¡ãŒã¿ãçŽæçã«èª¿æŽããå質管çã¢ã«ãŽãªãºã ã®åœ±é¿ãå³åº§ã«ç¢ºèªã§ããŸãã
第5ç« ïŒã±ãŒã¹ã¹ã¿ã㣠- å ç¢ãªãªã¯ã«ãŒãžã§ã³ã®å®è£
ãããã®æŠå¿µããDepth APIã®æãäžè¬çãªãŠãŒã¹ã±ãŒã¹ã§ãããªã¯ã«ãŒãžã§ã³ãšçµã³ã€ããŸããããç®æšã¯ãä»®æ³ãªããžã§ã¯ããçŸå®äžçã®ãªããžã§ã¯ãã®èåŸã«æ£ãã衚瀺ãããããã«ããããšã§ãã
äžå¿çãªããžãã¯ïŒãã©ã°ã¡ã³ãã·ã§ãŒããŒå ïŒ
ãã®ããã»ã¹ã¯ãä»®æ³ãªããžã§ã¯ãã®ãã¹ãŠã®ãã¯ã»ã«ã«å¯ŸããŠè¡ãããŸãã
- ä»®æ³ãã©ã°ã¡ã³ãã®æ·±åºŠãååŸ: é ç¹ã·ã§ãŒããŒã§ãé ç¹ã®ã¯ãªãã空éäœçœ®ãèšç®ããŸãããã®äœçœ®ã®Zæåã¯ãããŒã¹ãã¯ãã£ãé€ç®ã®åŸãä»®æ³ãªããžã§ã¯ãã®æ·±åºŠã衚ããŸãããã®å€ããã©ã°ã¡ã³ãã·ã§ãŒããŒã«æž¡ããŸãã
- çŸå®äžçã®æ·±åºŠãååŸ: ãã©ã°ã¡ã³ãã·ã§ãŒããŒã§ãçŸåšã®ä»®æ³ãã©ã°ã¡ã³ãã«å¯Ÿå¿ããæ·±åºŠãããå ã®ãã¯ã»ã«ãèŠã€ããå¿ èŠããããŸããAPIããæäŸããã`normDepthFromViewMatrix`ã䜿çšããŠããã©ã°ã¡ã³ãã®ãã¥ãŒç©ºéäœçœ®ã深床ãããã®ãã¯ã¹ãã£åº§æšã«å€æã§ããŸãã
- çŸå®ã®æ·±åºŠããµã³ããªã³ã°ããŠåŠç: ãããã®ãã¯ã¹ãã£åº§æšã䜿çšããŠãïŒçæ³çã«ã¯äºåã«ãã£ã«ã¿ãªã³ã°ããã³ã¢ãããµã³ããªã³ã°ãããïŒæ·±åºŠãããããµã³ããªã³ã°ããŸãã`rawValueToMeters`ã䜿çšããŠçã®å€ãã¡ãŒãã«ã«å€æããããšãå¿ããªãã§ãã ããã
- æ¯èŒããŠç Žæ£: ä»®æ³ãã©ã°ã¡ã³ãã®æ·±åºŠãšçŸå®äžçã®æ·±åºŠãæ¯èŒããŸããä»®æ³ãªããžã§ã¯ãããã®ãã¯ã»ã«ã«ããçŸå®äžçã®ãªããžã§ã¯ããããé ãã«ããïŒãã倧ããªæ·±åºŠå€ãæã€ïŒå Žåãããã¯ãªã¯ã«ãŒããããŠããŸããGLSLã§ã¯ã`discard`ããŒã¯ãŒãã䜿çšããŠãã®ãã¯ã»ã«ã®ã¬ã³ããªã³ã°ãå®å šã«åæ¢ããŸãã
å質管çãªãã®å Žå: ãªã¯ã«ãŒãžã§ã³ã®ãšããžã¯ïŒäœã空éè§£å床ã®ããã«ïŒãããã¯ç¶ã«ãªããïŒæéçãªãã€ãºã®ããã«ïŒããããããæ³¡ç«ã£ããããŸãããŸãã§ãã€ãºã®å€ããã¹ã¯ãä»®æ³ãªããžã§ã¯ãã«ç²éã«é©çšãããããã«èŠããŸãã
å質管çããã®å Žå: 第4ç« ã®ãã¯ããã¯ãé©çšããããšã§âæéçãã£ã«ã¿ãŒãå®è¡ããŠããŒã¿ãå®å®ããããšããžãæèããã¢ãããµã³ããªã³ã°æ¹æ³ã䜿çšããããšã§âãªã¯ã«ãŒãžã§ã³ã®å¢çã¯æ»ããã§å®å®ããŸããä»®æ³ãªããžã§ã¯ãã¯ãçŸå®ã®ã·ãŒã³ã®äžéšãšããŠå åºã§ä¿¡é Œæ§é«ãèŠããããã«ãªããŸãã
第6ç« ïŒããã©ãŒãã³ã¹ãããã©ãŒãã³ã¹ãããã©ãŒãã³ã¹
æ¯ãã¬ãŒã 深床ããŒã¿ãåŠçããããšã¯ãèšç®ã³ã¹ããé«ããªãå¯èœæ§ããããŸããäžé©åãªå®è£ ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ãã¬ãŒã ã¬ãŒããARã«ãšã£ãŠå¿«é©ãªéŸå€ä»¥äžã«ç°¡åã«åŒããã蟌ã¿ãåãæ°ãå¬ããããªäœéšã«ã€ãªãããŸãã以äžã¯ãè²ããªããã¹ããã©ã¯ãã£ã¹ã§ãã
GPUäžã§åŠçãå®çµããã
ã¡ã€ã³ã¬ã³ããŒã«ãŒãå ã§æ·±åºŠãã¯ã¹ãã£ããŒã¿ãCPUã«èªã¿æ»ãããšïŒäŸïŒ`readPixels`ã䜿çšïŒã¯çµ¶å¯Ÿã«ããªãã§ãã ããããã®æäœã¯ä¿¡ããããªãã»ã©é ããã¬ã³ããªã³ã°ãã€ãã©ã€ã³ã忢ããããã¬ãŒã ã¬ãŒããç Žå£ããŸãããã¹ãŠã®ãã£ã«ã¿ãªã³ã°ãã¢ãããµã³ããªã³ã°ãæ¯èŒããžãã¯ã¯GPUäžã®ã·ã§ãŒããŒã§å®è¡ããå¿ èŠããããŸãã
ã·ã§ãŒããŒãæé©åãã
- é©åãªç²ŸåºŠã䜿çšãã: å¯èœãªå Žåã¯ãæµ®åå°æ°ç¹æ°ããã¯ãã«ã«`highp`ã®ä»£ããã«`mediump`ã䜿çšããŸããããã«ãããã¢ãã€ã«GPUã§å€§å¹ ãªããã©ãŒãã³ã¹åäžãåŸãããããšããããŸãã
- ãã¯ã¹ãã£ã«ãã¯ã¢ãããæå°éã«æãã: ãã¹ãŠã®ãã¯ã¹ãã£ãµã³ãã«ã«ã¯ã³ã¹ããããããŸãããã£ã«ã¿ãŒãå®è£ ããéã¯ãå¯èœãªéããµã³ãã«ãåå©çšããããã«ããŠãã ãããäŸãã°ã3x3ã®ããã¯ã¹ãã©ãŒã¯ãå šäœã§ããå°ãªããã¯ã¹ãã£èªã¿åãã§æžã2ã€ã®ãã¹ïŒæ°Žå¹³1åãåçŽ1åïŒã«åé¢ã§ããŸãã
- åå²ã¯é«ã³ã¹ã: ã·ã§ãŒããŒå ã®è€éãª`if/else`æã¯ããã©ãŒãã³ã¹ã®åé¡ãåŒãèµ·ããå¯èœæ§ããããŸããæã«ã¯ãäž¡æ¹ã®çµæãèšç®ãã`mix()`ã`step()`ã®ãããªæ°åŠé¢æ°ã䜿çšããŠçµæãéžæããæ¹ãéãããšããããŸãã
WebXRæ©èœããŽã·ãšãŒã·ã§ã³ãè³¢ã䜿çšãã
`depth-sensing`æ©èœããªã¯ãšã¹ãããéã«ãèšå®ãå«ãèšè¿°åãæäŸã§ããŸãã
{ requiredFeatures: ['depth-sensing'],
depthSensing: {
usagePreference: ['cpu-optimized', 'gpu-optimized'],
dataFormatPreference: ['luminance-alpha', 'float32']
}
}
- usagePreference: `gpu-optimized`ã¯ãäž»ã«GPUã§æ·±åºŠããŒã¿ã䜿çšããããšã瀺åããããããªã¢ã«ã¿ã€ã ã¬ã³ããªã³ã°ã«æãŸãããã®ã§ãã`cpu-optimized`ã¯ãéåæã¡ãã·ã¥åæ§ç¯ãªã©ã®ã¿ã¹ã¯ã«äœ¿çšãããå ŽåããããŸãã
- dataFormatPreference: `float32`ããªã¯ãšã¹ããããšæé«ã®ç²ŸåºŠãåŸãããŸãããããã©ãŒãã³ã¹ã³ã¹ãããããå ŽåããããŸãã`luminance-alpha`ã¯16ãããã®æ·±åºŠå€ã2ã€ã®8ããããã£ã³ãã«ã«ããã£ãŠä¿åããã·ã§ãŒããŒã§åæ§ç¯ããããã«å°éã®ãããã·ããããžãã¯ãå¿ èŠã§ãããäžéšã®ããŒããŠã§ã¢ã§ã¯ããããã©ãŒãã³ã¹ãé«ãå ŽåããããŸããã·ã¹ãã ã¯å©çšå¯èœãªãã®ãæäŸãããããå®éã«åãåã£ã圢åŒãåžžã«ç¢ºèªããŠãã ããã
é©å¿çãªå質ãå®è£ ãã
ã¯ã³ãµã€ãºã»ãã£ããã»ãªãŒã«ã®å質ã¢ãããŒãã¯æé©ã§ã¯ãããŸããããã€ãšã³ãããã€ã¹ã¯è€éãªãã«ããã¹ã®ãã€ã©ãã©ã«ãã£ã«ã¿ãŒãåŠçã§ããŸãããããŒãšã³ãããã€ã¹ã¯èŠåŽãããããããŸãããé©å¿çãªå質ã·ã¹ãã ãå®è£ ããŠãã ããã
- èµ·åæã«ãããã€ã¹ã®ããã©ãŒãã³ã¹ããã³ãããŒã¯ããããã¢ãã«ã確èªããŸãã
- ããã©ãŒãã³ã¹ã«åºã¥ããŠãç°ãªãã·ã§ãŒããŒãŸãã¯ç°ãªããã£ã«ã¿ãªã³ã°ãã¯ããã¯ã®ã»ãããéžæããŸãã
- é«å質: æéçEMA + ãã€ã©ãã©ã«ãã£ã«ã¿ãŒ + ãšããžãæèããã¢ãããµã³ããªã³ã°ã
- äžå質: æéçEMA + åçŽãª3x3飿¥å¹³åã
- äœå質: ãã£ã«ã¿ãªã³ã°ãªããåºæ¬çãªãã€ãªãã¢è£éã®ã¿ã
ããã«ãããã¢ããªã±ãŒã·ã§ã³ãå¯èœãªéãå¹ åºãããã€ã¹ã§ã¹ã ãŒãºã«å®è¡ãããåãŠãŒã¶ãŒã«æé«ã®äœéšãæäŸã§ããŸãã
çµè«ïŒããŒã¿ããäœéšãž
WebXR Depth APIã¯æ°ããªã¬ãã«ã®æ²¡å ¥æãžã®å ¥ãå£ã§ãããå®ç§ãªARã®ããã®ãã©ã°ã¢ã³ããã¬ã€ãœãªã¥ãŒã·ã§ã³ã§ã¯ãããŸããããããæäŸããçããŒã¿ã¯åãªãåºçºç¹ã«éããŸãããçã®ç¿åŸã¯ãããŒã¿ã®äžå®å šæ§âãã®è§£å床ã®éçããã€ãºãç°å¢çãªåŒ±ç¹âãçè§£ããææ ®æ·±ãããã©ãŒãã³ã¹ãæèããå質管çãã€ãã©ã€ã³ãé©çšããããšã«ãããŸãã
æéçããã³ç©ºéçãã£ã«ã¿ãªã³ã°ãå®è£ ãã穎ãè§£å床ã®éããè³¢ãåŠçããããŒã¿ãåžžã«å¯èŠåããããšã§ããã€ãºã®å€ããžãã¿ãŒã®ããä¿¡å·ããããªãã®åµé çãªããžã§ã³ã®ããã®å®å®ããåºç€ã«å€ããããšãã§ããŸããè¡æçãªARãã¢ãšãçã«ä¿¡ããããæ²¡å ¥æã®ããäœéšãšã®éãã¯ããã°ãã°ãã®æ·±åºŠæ å ±ã®æ³šææ·±ã管çã«ãããŸãã
ãªã¢ã«ã¿ã€ã 深床ã»ã³ã·ã³ã°ã®åéã¯åžžã«é²åããŠããŸããå°æ¥ã®é²æ©ã¯ãAIã«ãã£ãŠåŒ·åãããæ·±åºŠåæ§ç¯ãã»ãã³ãã£ãã¯çè§£ïŒãã¯ã»ã«ããåºãã«å±ããã®ãã人ãã«å±ããã®ããç¥ãããšïŒããããŠããé«è§£å床ã®ã»ã³ãµãŒãããå€ãã®ããã€ã¹ã«ãããããããããŸãããããããå質管çã®åºæ¬ååâããŒã¿ã®å¹³æ»åããã£ã«ã¿ãªã³ã°ãæ€èšŒâã¯ããªãŒãã³ãŠã§ãäžã§æ¡åŒµçŸå®ã®å¯èœæ§ã®éçãæŒãåºããããšçå£ã«èãããã¹ãŠã®éçºè ã«ãšã£ãŠãäžå¯æ¬ ãªã¹ãã«ã§ããç¶ããã§ãããã