├── ARButton.js ├── demo.gif ├── index.html ├── main.css ├── readme.md └── three.module.js /ARButton.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com 3 | * @author Mugen87 / https://github.com/Mugen87 4 | */ 5 | 6 | var ARButton = { 7 | 8 | createButton: function ( renderer ) { 9 | 10 | function showStartAR( /*device*/ ) { 11 | 12 | var currentSession = null; 13 | 14 | function onSessionStarted( session ) { 15 | 16 | session.addEventListener( 'end', onSessionEnded ); 17 | 18 | /* 19 | session.updateWorldTrackingState( { 20 | 'planeDetectionState': { 'enabled': true } 21 | } ); 22 | */ 23 | 24 | renderer.xr.setReferenceSpaceType( 'local' ); 25 | renderer.xr.setSession( session ); 26 | button.textContent = 'STOP AR'; 27 | 28 | currentSession = session; 29 | 30 | } 31 | 32 | function onSessionEnded( /*event*/ ) { 33 | 34 | currentSession.removeEventListener( 'end', onSessionEnded ); 35 | 36 | button.textContent = 'START AR'; 37 | 38 | currentSession = null; 39 | 40 | } 41 | 42 | // 43 | 44 | button.style.display = ''; 45 | 46 | button.style.cursor = 'pointer'; 47 | button.style.left = 'calc(50% - 50px)'; 48 | button.style.width = '100px'; 49 | 50 | button.textContent = 'START AR'; 51 | 52 | button.onmouseenter = function () { 53 | 54 | button.style.opacity = '1.0'; 55 | 56 | }; 57 | 58 | button.onmouseleave = function () { 59 | 60 | button.style.opacity = '0.5'; 61 | 62 | }; 63 | 64 | button.onclick = function () { 65 | 66 | if ( currentSession === null ) { 67 | 68 | navigator.xr.requestSession( 'immersive-ar' ).then( onSessionStarted ); 69 | 70 | } else { 71 | 72 | currentSession.end(); 73 | 74 | } 75 | 76 | }; 77 | 78 | } 79 | 80 | function disableButton() { 81 | 82 | button.style.display = ''; 83 | 84 | button.style.cursor = 'auto'; 85 | button.style.left = 'calc(50% - 75px)'; 86 | button.style.width = '150px'; 87 | 88 | button.onmouseenter = null; 89 | button.onmouseleave = null; 90 | 91 | button.onclick = null; 92 | 93 | } 94 | 95 | function showARNotSupported() { 96 | 97 | disableButton(); 98 | 99 | button.textContent = 'AR NOT SUPPORTED'; 100 | 101 | } 102 | 103 | function stylizeElement( element ) { 104 | 105 | element.style.position = 'absolute'; 106 | element.style.bottom = '20px'; 107 | element.style.padding = '12px 6px'; 108 | element.style.border = '1px solid #fff'; 109 | element.style.borderRadius = '4px'; 110 | element.style.background = 'rgba(0,0,0,0.1)'; 111 | element.style.color = '#fff'; 112 | element.style.font = 'normal 13px sans-serif'; 113 | element.style.textAlign = 'center'; 114 | element.style.opacity = '0.5'; 115 | element.style.outline = 'none'; 116 | element.style.zIndex = '999'; 117 | 118 | } 119 | 120 | if ( 'xr' in navigator ) { 121 | 122 | var button = document.createElement( 'button' ); 123 | button.style.display = 'none'; 124 | 125 | stylizeElement( button ); 126 | 127 | navigator.xr.isSessionSupported( 'immersive-ar' ).then( function ( supported ) { 128 | 129 | supported ? showStartAR() : showARNotSupported(); 130 | 131 | } ).catch( showARNotSupported ); 132 | 133 | return button; 134 | 135 | } else { 136 | 137 | var message = document.createElement( 'a' ); 138 | message.href = 'https://immersiveweb.dev/'; 139 | 140 | if ( window.isSecureContext === false ) { 141 | 142 | message.innerHTML = 'WEBXR NEEDS HTTPS'; // TODO Improve message 143 | 144 | } else { 145 | 146 | message.innerHTML = 'WEBXR NOT AVAILABLE'; 147 | 148 | } 149 | 150 | message.style.left = 'calc(50% - 90px)'; 151 | message.style.width = '180px'; 152 | message.style.textDecoration = 'none'; 153 | 154 | stylizeElement( message ); 155 | 156 | return message; 157 | 158 | } 159 | 160 | } 161 | 162 | }; 163 | 164 | export { ARButton }; 165 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nosy-b/holography/a5ea0985018fbdaded2a7392aaa6fd9c05565e4b/demo.gif -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Holograms 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 25 |
26 |
27 | 28 |

When in AR mode, create an hologram by looking at a person/face/photo and tap on the screen, it should appear gently. (Beware of camera framing, not too close)

29 | 30 |
31 |
32 | 33 |
34 |
35 | 36 | 94 | 95 | 127 | 128 | 557 | 558 | 559 | 560 | -------------------------------------------------------------------------------- /main.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | background-color: #000; 4 | color: #fff; 5 | font-family: Monospace; 6 | font-size: 13px; 7 | line-height: 24px; 8 | overscroll-behavior: none; 9 | overflow:hidden; 10 | } 11 | 12 | a { 13 | color: rgb(240, 205, 140); 14 | text-decoration: none; 15 | } 16 | 17 | a:hover { 18 | text-decoration: underline; 19 | } 20 | 21 | button { 22 | cursor: pointer; 23 | text-transform: uppercase; 24 | } 25 | 26 | canvas { 27 | display: block; 28 | } 29 | .containerV { position:relative; } 30 | .containerV video { 31 | position:relative; 32 | z-index:0; 33 | } 34 | .overlay { 35 | 36 | z-index:1; 37 | color: white; 38 | text-align: center; 39 | margin: 12px; 40 | margin-top: 42px; 41 | } 42 | .red-square { 43 | background-color: #FF4136; 44 | width: 300px; 45 | height: 300px; 46 | position: absolute; 47 | left: 50%; 48 | top: 50%; 49 | transform: translate(-50%, -50%); 50 | } 51 | #info { 52 | position: absolute; 53 | top: 0px; 54 | width: 100%; 55 | padding: 10px; 56 | box-sizing: border-box; 57 | text-align: center; 58 | -moz-user-select: none; 59 | -webkit-user-select: none; 60 | -ms-user-select: none; 61 | user-select: none; 62 | pointer-events: none; 63 | z-index: 1; /* TODO Solve this in HTML */ 64 | } 65 | 66 | .linkG { 67 | font-size:xx-small; 68 | color: white; 69 | } 70 | 71 | #infoSeismic { 72 | position: absolute; 73 | top: 0px; 74 | width: 280px; 75 | padding: 10px; 76 | box-sizing: border-box; 77 | text-align: center; 78 | -moz-user-select: none; 79 | -webkit-user-select: none; 80 | -ms-user-select: none; 81 | user-select: none; 82 | pointer-events: none; 83 | z-index: 1; /* TODO Solve this in HTML */ 84 | background-color: rgba(35, 4, 83, 0.6); 85 | } 86 | 87 | a, button, input, select { 88 | pointer-events: auto; 89 | } 90 | 91 | .dg.ac { 92 | -moz-user-select: none; 93 | -webkit-user-select: none; 94 | -ms-user-select: none; 95 | user-select: none; 96 | z-index: 2 !important; /* TODO Solve this in HTML */ 97 | } 98 | 99 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Holography 2 | 3 | Simple demo of WebXR and Deep Learning using Tensorflow to create holograms on-the-fly. 4 | It works on Android with the last Chrome (>= r81) 5 | 6 | ! REMARK! : I discovered that the possibility to take pictures WHILE in AR Context just works on LG phones surprisingly (https://developers.google.com/ar/discover/supported-devices) as they use the wide angle camera for AR (the phone I used by chance)!! So to use this demo with other phones, take the picture (using usual browser get media api) but before launching the AR Context! 7 | 8 | ![alt text](https://raw.githubusercontent.com/nosy-b/holography/master/demo.gif "Holography") 9 | 10 | DEMO here: http://nosy-b.github.io/holography 11 | 12 | ## How to 13 | 14 | - First be sure to have an android phone with chrome >=r81 15 | - Choose your camera feed (ideally back camera) 16 | - Tap on start AR (the position of your phone at that moment will be the center of the frame) 17 | - Move a bit around if you want to help the space detection 18 | - Look at a human (real or a photo) and tap on the screen 19 | - It should appear coming from your phone to the direction you were looking at when clicked on Start (initial position) 20 | 21 | ## Description 22 | 23 | Small code that create particles for people extracted from camera feed using Bodypix model 24 | Feel free to use this dirty little code for your own experiments 25 | I put demos on my twitter sometimes https://twitter.com/AlexandreDevaux 26 | 27 | ## Getting Started 28 | 29 | ### Dependencies 30 | 31 | * ThreeJS, TensorFlowJS 32 | 33 | 34 | ## Help 35 | 36 | One thing to be careful about is not to frame too close the subject you want to make a hologram of. The camera frame is smaller than what your screen shows. (A good todo would be to show camera frame while in AR) 37 | 38 | ## Authors 39 | 40 | Alexandre Devaux 41 | [@AlexandreDevaux](https://twitter.com/AlexandreDevaux) 42 | 43 | ## Version History 44 | 45 | 46 | 47 | ## License 48 | 49 | Check the license of THREEJS and Tensorflow 50 | 51 | --------------------------------------------------------------------------------