Inside

panolens.js로 360° 공간을 보여주다

360° 영상을 웹에서 구현하는 방법
임상아 뉴스룸 디벨로퍼|동아일보 디프런티어센터 2023-04-13 10:00:01
이번 히어로콘텐츠팀 6기에서는 현장을 생생하게 보여주는 사진, 영상, 음성 자료들이 많았다. 디지털 페이지에서는 이런 자료들을 최대한 활용하고자 했다. 360° 영상을 활용한 <'표류' 속으로> 기사도 그러한 취지에서 기획됐다. ‘표류’는 단순히 한 공간에서 일어나는 것이 아니라 여러 공간에서 복합적인 이유들로 일어나게 된다. 한 공간 안에서도 다양한 일들이 동시다발적으로 일어나고 있기 때문에, 360°로 공간을 보여주면 긴박하게 돌아가는 현장을 잘 보여줄 수 있겠다고 생각했다.
진행 전 테스트는 필수
다른 페이지들과 다르게 360° 영상은 진행 여부를 판단하기까지 확인해야 할 요소들이 많았다. 현장에서 쉽게 촬영해 오는 것이 가능한 지, 어떤 각도에서 찍어야 하는지, 실제 영상이 웹페이지에서 잘 구동되는지가 모두 확인이 되어야 진행할 수 있었다.

여의도에 있는 한 카메라 대여점에 가서 360° 영상을 찍을 수 있는 카메라(Insta360 X2)를 직접 대여했다. 그리고 빈 회의실에 들어가 촬영을 했다. 삼각대로 카메라를 고정시켜두고 촬영 버튼을 누르면 알아서 360°로 영상이 찍힌다. 찍은 영상은 .insv라는 특이한 확장자명으로 저장되는데, Insta360 STUDIO라는 프로그램으로 열어서 확인할 수 있다. VID_로 시작하는 파일을 열면 원하는 길이로 편집이 가능하고, mp4 형식으로 내보낼 수 있다. 생각보다 촬영도 간단하고, 편집한 영상을 웹페이지에 올렸을 때도 큰 문제가 없어 그대로 진행하기로 했다.
panolens.js를 선택한 이유
웹페이지에 360° 영상을 띄우는 방식은 굉장히 다양한데, 가장 대표적인 방법은 three.js를 사용하는 것이다. 커다란 3D 구를 만들고, 그 안을 360° 영상으로 맵핑하는 방식이다.
하지만 이번 기사는 단순히 360° 영상을 페이지에 띄우는 것만으로 끝나지 않았다. 독자가 직접 360° 영상을 둘러보고, 궁금한 부분들을 눌러볼 수 있게 만들어야 했다. 이 과정에서 three.js로 직접 모든 코드를 짜기에는 시간이 오래 걸리고, 굉장히 복잡해질 것 같다고 생각했다. 그래서 360° 영상을 좀 더 쉽게 웹에서 구현할 수 있는 라이브러리들을 찾아봤다. 360° 뷰어 라이브러리는 굉장히 다양했는데, 그 중에서 가장 문서 정리가 잘 되어있고, 원하는 기능이 한 눈에 보였던 panolens.js라는 라이브러리를 사용하게 됐다.

paonlens.js는 three.js를 기반으로 한 라이브러리로, 매우 간단한 코드로 360° 사진, 영상을 웹에 띄울 수 있고, 파노라마와 관련된 여러 기능들을 제공한다.
panolens.js의 가장 큰 장점은 코드 작성이 간단하다는 것이다. 위의 코드를 보면 알 수 있듯이, 360° 이미지를 웹페이지에 띄우기 위해서 three.js로는 10줄 넘게 작성해야 하지만, panolens.js를 사용하면 단 4줄로 구현이 가능하다. 또한 마우스 드래그로 360° 영상을 둘러볼 수 있는 기능도 panolens.js에는 자동으로 포함되어 있다.

panolens.js의 기본적인 사용법은 공식 페이지 예시, 공식 문서에 잘 정리되어 있으니 한 번 살펴보는 것을 추천한다. 여기에서는 panolens.js를 이용해 <‘표류' 속으로>와 같이 클릭 버튼들을 추가해야 하는 경우, 360° 영상들을 여러 개 사용하는 경우에 쓸 수 있는 팁들을 소개하려고 한다.
panolens.js로 클릭 버튼 만들기
<'표류' 속으로>에서는 각 장소마다 곳곳에 클릭해볼 수 있는 + 버튼들이 있다. panolens.js를 사용하게 된 결정적인 이유는 바로 이 클릭 버튼들을 매우 간단하게 추가할 수 있었기 때문이다. 파노라마는 평면처럼 보여도 3D 공간 안에 있는 것이기 때문에, css로 버튼의 위치를 지정해도 사용자가 드래그하는 순간 위치가 어긋나버린다. 즉 버튼 역시 3D 공간 안에 존재하는 three.js의 material로 추가해야 한다는 것이다. panolens.js에서는 infoSpot 기능을 통해 간단하게 파노라마 위에 버튼을 추가할 수 있다.
위의 코드처럼 new PANOLENS.Infospot()에 3가지 인자를 넣어주면 되는데, 선택사항이라 넣지 않으면 모두 기본값(300, PANOLENS.DataImage.Info, true)으로 버튼이 만들어진다. 마지막 호버 효과는 ‘true’로 설정할 경우 버튼에 마우스를 올렸을 때 버튼이 살짝 확대된다. infoSpot을 만든 후에는 x,y,z 위치를 지정해줘야 한다.
그렇다면 원하는 위치의 x,y,z 좌표값은 어떻게 구하면 될까? 값을 하나씩 넣어가며 확인해볼 수 있겠지만, 매우 번거로운 작업이 될 것이다. 특히 <'표류' 속으로>처럼 여러 곳에 버튼을 띄워야하는 경우에는 시간도 오래 걸릴 것이다. 이럴 때 three.js에서 좌표값 등을 편하게 구할 수 있는 라이브러리가 있다. dat.gui는 웹에서 특정 요소의 색상, 값 등을 조절하는 컨트롤바를 만들 수 있는 라이브러리다.
html에 dat.gui의 cdn를 넣고, 자바스크립트 파일에 조정하고 싶은 요소와 그 요소의 값들을 지정해서 넣으면 된다. 아래 코드는 infoSpot의 x,y,z값들을 최솟값 -5000, 최댓값 5000, 100 단위로 조정할 수 있는 컨트롤바를 생성한다.
위의 코드를 넣으면 이렇게 페이지 오른쪽 상단에 값을 조정할 수 있는 컨트롤바가 생긴다. 하늘색 막대를 왼쪽, 오른쪽으로 드래그해 값을 100단위로 조정할 수 있고, 직접 값을 입력할 수도 있다. 값들을 조정하면 화면에 실시간으로 반영되어 infoSpot의 위치가 움직인다. 원하는 위치로 조정한 [x,y,z] 값들을 배열로 저장하고, for문을 통해 각 infoSpot(버튼)들의 위치로 지정해줬다.
이 dat.gui를 이용하면 infospot의 위치들 뿐만 아니라, 숫자값을 가지고 있는 것이라면 어떤 것이든 조정해서 확인해볼 수 있다. <'표류' 속으로>에서 각 장소에 처음 들어갔을 때 나오는 카메라 시점 또한 viewer.camera.position의 x,y,z값을 dat.gui로 확인해서 지정해줬다.
infoSpot은 이미지 경로를 지정해주지 않을 경우 panolens.js에서 디폴트로 설정되어 있는 아이콘 이미지(맨 왼쪽)가 뜬다. 원하는 이미지로 설정할 경우 가운데처럼 바뀌는데, 문제는 아이콘에 이미지를 씌우는 과정에서 화질 저하가 일어난다. 특히 마지막 ‘닥터헬기’에서 텍스트가 들어있는 아이콘을 넣으니 그 현상이 더 눈에 띄었다. panolens.js의 기본 설정 때문에 일어나는 현상이라 js 파일을 직접 수정해야 했다. 그래서 깃허브에서 panolens.js 파일을 직접 다운 받아서 코드를 아래와 같이 수정했다. infoSpot을 설정하는 함수 안에 texture.minFilter = THREE.LinearFilter;를 추가하면 원래 이미지 파일 그대로 나오게 된다.
panolens.js로 영상 전환 및 회전 효과 적용하기
<'표류' 속으로>는 특정 버튼을 클릭할 때마다 360° 영상이 바뀐다. 이 기능 역시 panolens.js에서 간단하게 제공하고 있다. viewer.setPanorama()라는 함수에 인자로 원하는 panorama 변수를 넣어주면 단순히 영상이 교체될 뿐만 아니라, 자동으로 페이드인-페이드아웃 효과까지 적용된다.

그리고 <'표류' 속으로>에서는 각 장소에 처음 들어가면 360° 영상이 자동으로 회전된다. 이 회전 기능이 단순하지만 코드를 짜면서 예상 외로 난관에 부딪혔던 부분이었다. 영상을 회전하는 것은 panorama viewer에 autoRotate = ‘true’ 속성만 넣어주면 된다. 문제는 ‘들어가기’ 버튼을 누르면 이 회전이 멈추도록 해야했는데, autoRotate = ‘false’는 먹히지 않았다. 공식 문서에서 ‘rotate’로 찾았을 때도 autoRotate 기능 이외에 다른 것은 발견할 수 없었다. 그렇게 몇 시간을 헤맨 뒤에 뒤늦게 panolens 문서에서 자동회전과 자동회전을 멈추는 함수를 발견했다. 관련 함수를 찾지 못했던 이유는 그 함수명이 enableAutoRate()와 disableAutorate() 였기 때문이다. 오타인지 모르겠으나 특이하게 Auto”Rotate”가 아닌 Auto”Rate”로 되어 있어서 검색해도 나오지 않았던 것이다. 이 두 함수를 적용하니 자동회전이 잘 제어됐다.
360° 영상 / penolens.js 사용시 고려해야 할 점
360° 영상을 웹에서 사용할 때 고려해야 될 점은 영상 파일의 크기가 생각보다 페이지 성능에 큰 영향을 미친다는 것이다. 모든 기능을 다 제외하고, 360° 영상 4개가 버튼을 통해 전환되게 하는 것만 넣었을 때도 영상이 조금이라도 무거울 경우에는 특정 기기에서 제대로 동작이 안되는 경우가 있었다. 그래서 모든 기기에서 잘 작동하기 위해서는 영상 파일의 크기를 최대한 줄이는 것이 좋다. 코드를 짠 시간만큼이나 프리미어를 이용해 영상을 편집하는 것에도 굉장히 많은 시간을 썼다. 여러 시도를 해 본 결과, 영상 길이를 최대한 줄이고 비트전송률을 낮추는 것이 영상의 크기를 줄이는 데 가장 효과적이었다. 촬영해 온 영상의 좋은 화질 그대로 사용하지 못한 점은 많이 아쉬운 부분이다.

panolens.js는 짧은 코드로 복잡한 기능을 간단하게 구현할 수 있다는 장점이 있다. 하지만 더 세밀한 부분들까지 조정하고 싶다면 panlens.js 파일을 직접 수정해야 한다. 그럼에도 three.js로 직접 코드를 짜는 것보다 훨씬 효율적인 작업이 가능하다. 360° 영상을 웹페이지에 띄우고 사용자와 간단하게 인터랙션하는 페이지를 만들고 싶다면 panolens.js를 한 번 사용해보는 것을 추천한다.
관련 콘텐츠 더보기
표류 : 생사의 경계를 떠돌다 응급환자가 제대로 된 치료를 받지 못하고 무력하게 떠도는 ‘표류’는 운이 나쁜 누군가가, 어쩌다 겪는 일이 아닙니다.
응급실과 구급차에서 37일을 보내며 26명의 ‘표류’ 환자와 그 가족을 인터뷰했습니다.
2023.03.27~04.03·히어로콘텐츠 6기·
임상아 뉴스룸 디벨로퍼
임상아 뉴스룸 디벨로퍼|동아일보 디프런티어센터

디오리지널의 기사를 기술적으로 구현하는 일을 하고 있습니다. 이야기와 기술이 만날 때 이야기가 전달할 수 있는 가치는 더욱 극대화될 수 있다고 생각합니다. 많은 사람들에게 새로움과 감동을 줄 수 있는 기사들을 만들어가고 싶습니다.