Aframe ipd 관련 자료 검토

360VR

Aframe.js 에서 IPD 설정이 가능한지 여부를 확인이 필요했다. 우선 IPD가 무엇인지 알아보자.

IPD

IPD: Inter pupillary distance, 동공 거리

양쪽 눈의 동공 중심을 잇는 선의 거리. 사람에 따라 다소 차이는 있으나 대개 65mm이다. [네이버지식백과] 그런데 사람에 따라 동공사이의 거리가 조금씩 다르고 화면을 VR모드로 변경해서 카드보드를 쓰면 초점이 맞지 않을 수 있다.

그래서 VR기기에서 물리적 IPD의 거리를 조절할 수 있게 지원을 하거나 KRPANO처럼 소프트웨어에서 조절을 할 수 있도록 지원한다. aframe ipd

Aframe에서 IPD 검색

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
52
53
54
/**
     * Assumes 2 cameras that are parallel and share an X-axis, and that
     * the cameras' projection and world matrices have already been set.
     * And that near and far planes are identical for both cameras.
     * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765
     */
    function setProjectionFromUnion( camera, cameraL, cameraR ) {
 
        cameraLPos.setFromMatrixPosition( cameraL.matrixWorld );
        cameraRPos.setFromMatrixPosition( cameraR.matrixWorld );
 
        var ipd = cameraLPos.distanceTo( cameraRPos );
 
        var projL = cameraL.projectionMatrix.elements;
        var projR = cameraR.projectionMatrix.elements;
 
        // VR systems will have identical far and near planes, and
        // most likely identical top and bottom frustum extents.
        // Use the left camera for these values.
        var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
        var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
        var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ];
        var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ];
 
        var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ];
        var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ];
        var left = near * leftFov;
        var right = near * rightFov;
 
        // Calculate the new camera's position offset from the
        // left camera. xOffset should be roughly half `ipd`.
        var zOffset = ipd / ( - leftFov + rightFov );
        var xOffset = zOffset * - leftFov;
 
        // TODO: Better way to apply this offset?
        cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale );
        camera.translateX( xOffset );
        camera.translateZ( zOffset );
        camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale );
        camera.matrixWorldInverse.getInverse( camera.matrixWorld );
 
        // Find the union of the frustum values of the cameras and scale
        // the values so that the near plane's position does not change in world space,
        // although must now be relative to the new union camera.
        var near2 = near + zOffset;
        var far2 = far + zOffset;
        var left2 = left - xOffset;
        var right2 = right + ( ipd - xOffset );
        var top2 = topFov * far / far2 * near2;
        var bottom2 = bottomFov * far / far2 * near2;
 
        camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 );
 
    }
cs

setProjectionFromUnion에서 IPD을 찾을 수 있었다. setProjectionFromUnion은 setProjectionFromUnion은 this.getCamera = function ( camera ) 함수에서 호출된다.

this.getCamera = function ( camera )

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
this.getCamera = function ( camera ) {
 
    if ( isPresenting() ) {
 
        var parent = camera.parent;
        var cameras = cameraVR.cameras;
        var object = poseTarget || camera;
 
        updateCamera( cameraVR, parent );
 
        for ( var i = 0; i < cameras.length; i ++ ) {
 
            updateCamera( cameras[ i ], parent );
 
        }
 
        // update camera and its children
        object.matrixWorld.copy( cameraVR.matrixWorld );
 
        var children = object.children;
 
        for ( var i = 0, l = children.length; i < l; i ++ ) {
 
            children[ i ].updateMatrixWorld( true );
 
        }
 
        setProjectionFromUnion( cameraVR, cameraL, cameraR );
 
        return cameraVR;
 
    }
 
    return camera;
 
};
cs

하지만 관련 부분을 수정하고 테스트를 해봤지만 별다른 소득을 얻을 수 없었다. 나중에 알게된 사실이지만 WebXRManager에서 관련 부분을 다루고 있다고 본 것 같기도 하다.

IPD값 변경해 보기

aframe ipd 직접 0.03~0.09로 수정을 해보고 렌더링 해봤는데 그 차이를 크게 느낄 수 없었다.