Panolens ipd 설정
IPD…그리고
panolens에서 IPD를 따로 설정해 주는 부분이 없다. 깃허브에도 따로 언급된 부분도 없다.
간단하게 눈사이의 거리를 담당하는 변수가 따로 있고, 이 변수의 크기만 조절하면 될 것 같다는 생각을 했다. 일단 VR Mode로 화면을 전환하는 부분에서 부터 코드 역추적을 시작했다.
StereoEffect
소스에서 Stereoscopic으로 검색을 해서 따라가니 PANOLENS.Modes를 확인할 수 있었다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /** * @memberOf PANOLENS * @enum {number} */ PANOLENS.Modes = { /** Unknown */ UNKNOWN: 0, /** Normal */ NORMAL: 1, /** Google Cardboard*/ CARDBOARD: 2, /** Stereoscopic **/ STEREO: 3 }; | cs |
설정 화면에서 선택하면 각각 0, 1, 2, 3으로 설정된다.
또 Stereoscopic 관련 부분을 찾을 수 있었는데 enableEffect 함수와 연결되어 있었다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | { title: 'Mode', subMenu: [ { title: 'Normal', handler: handler( 'disableEffect' ) }, { title: 'Cardboard', handler: handler( 'enableEffect', PANOLENS.Modes.CARDBOARD ) }, { title: 'Stereoscopic', handler: handler( 'enableEffect', PANOLENS.Modes.STEREO ) } ] } | cs |
enableEffect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | PANOLENS.Viewer.prototype.enableEffect = function ( mode ) { if ( this.mode === mode ) { return; } if ( mode === PANOLENS.Modes.NORMAL ) { this.disableEffect(); return; } else { this.mode = mode; } var fov = this.camera.fov; switch( mode ) { case PANOLENS.Modes.CARDBOARD: this.effect = this.CardboardEffect; this.enableReticleControl(); break; case PANOLENS.Modes.STEREO: this.effect = this.StereoEffect; this.enableReticleControl(); break; default: this.effect = null; this.disableReticleControl(); break; } this.activateWidgetItem( undefined, this.mode ); /** * Dual eye effect event * @type {object} * @event PANOLENS.Viewer#panolens-dual-eye-effect * @event PANOLENS.Infospot#panolens-dual-eye-effect * @property {PANOLENS.Modes} mode - Current display mode */ this.dispatchEventToChildren( { type: 'panolens-dual-eye-effect', mode: this.mode } ); // Force effect stereo camera to update by refreshing fov this.camera.fov = fov + 10e-3; this.effect.setSize( this.container.clientWidth, this.container.clientHeight ); this.render(); this.camera.fov = fov; }; | cs |
함수는 위와가 같이 작성이 되어 있었고 StereoEffect, CardboardEffect 단어가 눈에 들어왔다. 다시 CardboardEffect으로 검색하니 PANOLENS.Viewer의 생성자에서 찾을 수 있엇다.
StereoEffect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | THREE.StereoEffect = function ( renderer ) { var _stereo = new THREE.StereoCamera(); _stereo.aspect = 0.5; this.setEyeSeparation = function ( eyeSep ) { _stereo.eyeSep = eyeSep; }; this.setSize = function ( width, height ) { renderer.setSize( width, height ); }; this.render = function ( scene, camera ) { scene.updateMatrixWorld(); if ( camera.parent === null ) camera.updateMatrixWorld(); _stereo.update( camera ); var size = renderer.getSize(); if ( renderer.autoClear ) renderer.clear(); renderer.setScissorTest( true ); renderer.setScissor( 0, 0, size.width / 2, size.height ); renderer.setViewport( 0, 0, size.width / 2, size.height ); renderer.render( scene, _stereo.cameraL ); renderer.setScissor( size.width / 2, 0, size.width / 2, size.height ); renderer.setViewport( size.width / 2, 0, size.width / 2, size.height ); renderer.render( scene, _stereo.cameraR ); renderer.setScissorTest( false ); }; }; | cs |
쭉~ 코드를 읽어 가다가 setEyeSeparation? EyeSeparation을 set하는 함수인데 EyeSeparation가 뭐지? 번역을 해보니 눈 분리!!! _stereo.eyeSep 값이 얼마로 설정되어 있는지 확인하니 _stereo는 three.js 의 new THREE.StereoCamera 였다.
new THREE.StereoCamera
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | THREE.StereoEffect = function ( renderer ) { var _stereo = new THREE.StereoCamera(); _stereo.aspect = 0.5; this.setEyeSeparation = function ( eyeSep ) { _stereo.eyeSep = eyeSep; }; this.setSize = function ( width, height ) { renderer.setSize( width, height ); }; this.render = function ( scene, camera ) { scene.updateMatrixWorld(); if ( camera.parent === null ) camera.updateMatrixWorld(); _stereo.update( camera ); var size = renderer.getSize(); if ( renderer.autoClear ) renderer.clear(); renderer.setScissorTest( true ); renderer.setScissor( 0, 0, size.width / 2, size.height ); renderer.setViewport( 0, 0, size.width / 2, size.height ); renderer.render( scene, _stereo.cameraL ); renderer.setScissor( size.width / 2, 0, size.width / 2, size.height ); renderer.setViewport( size.width / 2, 0, size.width / 2, size.height ); renderer.render( scene, _stereo.cameraR ); renderer.setScissorTest( false ); }; }; | cs |
여기서 보니 eyeSep 값이 0.064로 내가 알고 있던 ipd의 평균 수치 (60mm~65mm)의 값과 근사해서 혹시나 싶었다. panolens의 기본 예제에서 증가버튼, 감소버튼, eyeSep 출력을 추가하고 eyeSep 을 조절하면 KRpano의 IPD 설정과 똑같이 동작하는지 확인했다.
KRPANO IPD
구현물
결과
코딩 결과를 비교해서 보니 동작하는 모습이 비슷해보였다. 실제로 IPD의 값이 안맞은 예제나 핸드폰이 있으면 가지고 테스트할 가치가 있다.