개발/js

[JS] model-viewer 사용법 1 - web에 3D 모델을 띄우자!

waterpole-dev 2022. 9. 13. 15:35
반응형

구글에서 제공하는 라이브러리인 model-viewer를 사용해서 web에 3D 모델을 띄우고, AR까지 적용시켜봅시다!

문서가 많이 없더라고요..

 

조금은 간결하게 다룰 예정이라

더 자세한 내용은 공식문서 보시면 됩니다. 쉽게 적혀있어요


설치

glitch 같은 방법도 있지만 npm 혹은 cdn을 이용해서 설치를 진행하겠습니다.

// npm
npm install @google/model-viewer

// cdn
<script type="module" src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script>

모델 띄우기

지원되는 3D 모델은 glTF/GLB 파일입니다.

<model-viewer id="model-ex" src="sample.glb" alt="model sample" camera-controls></model-viewer>
  • src
    • 3D 모델 glTF/GLB 파일
  • camera-controls
    • 마우스/터치로 제어가 가능해집니다. 사실상 필수 기본값입니다.

저는 우선 위 3가지만 설정해주도록 하겠습니다.


모달로 띄우기

자 우선 여기까지만 해도 web에 3D 모델이 보이기 시작합니다.

그대로 둬도 괜찮지만, 저는 감춰놨다가 리스트에서 '3D' 버튼을 클릭하면 modal로 띄워주겠습니다.

<button class="open-model-btn">3D</button>

<div class="mv-modal-box">
    <model-viewer id="model-ex" src="sample.glb" alt="model sample" camera-controls></model-viewer>
</div>
.mv-modal-box {
    display: none;
}
const MV_MODAL_BOX = document.querySelector('.mv-modal-box');
const modelOpenBtn = document.querySelector('.open-model-btn');

modelOpenBtn.addEventListener('click', () => {
    MV_MODAL_BOX.style.display = 'block';
})

이제 버튼을 누르면 display: none 되어있던 'mv-modal-box'가 노출됩니다.

하지만 이렇게 되면 src가 고정적이라 확장성이 떨어지게 됩니다.

버튼을 몇 개 더 추가해서 각 버튼을 누를 때마다 버튼에 맞는 3D 모델을 노출하도록 수정을 해주겠습니다.


확장하기

<button class="open-model-btn" data-product-name="robot">3D - 01</button>
<button class="open-model-btn" data-product-name="phone">3D - 02</button>
<button class="open-model-btn" data-product-name="car">3D - 03</button>

<div class="mv-modal-box">
    <model-viewer id="model-ex" camera-controls></model-viewer>
</div>

버튼에 'data-product-name'을 추가했습니다.

클릭한 버튼에서 attr 속성을 가져와 해당 속성과 일치하는 모델을 로드시켜주기 위함입니다.

 

model-viewer의 src와 alt 속성은 제거하였습니다.

사용자가 처음에 어떤 모델을 누를지 모르는 상황에서 굳이 하나를 로드시키는 건 자원낭비라고 생각했기 때문입니다.

const MV_MODAL_BOX = document.querySelector('.mv-modal-box');
const MODAL_VIEWER = document.querySelector('#model-ex');
const modelOpenBtn = document.querySelector('.open-model-btn');

modelOpenBtn.addEventListener('click', (e) => {
    const target = e.currentTarget;
    const productName = target.getAttribute('data-product-name');
    
    MV_MODAL_BOX.style.display = 'block';
    loadModel(productName)
});

function loadModel(name) {
    const modelSrc = `./assets/model/${name}.glb`;
    MODEL_VIEWER.setAttribute('src', modelSrc);
}

이제 각 버튼을 클릭할 때마다 robot.glb, phone.glb, car.glb로 src가 변경될 것입니다.

src가 변경되면 자동으로 model-viewer는 리로드 됩니다. (로드되었던 모델은 캐싱되어 남아있음)

 

근데 이상합니다.

모델을 변경할 때마다 모델을 이리저리 돌려놓은 카메라 궤도가 그대로 유지되고, 모델만 변경되고 있습니다.

이를 해결해봅시다.


모델 로드 시 카메라 궤도 초기화

맨 위에 링크 걸었던 공식 문서에 loading > event로 가보시면 load라는 이벤트가 있습니다.

load이벤트는 src 속성이 변경될 때마다 실행됩니다. (model-visibility와는 다름)

 

load 외에 모델이 로드되는 과정을 0 ~ 1로 제공해주는 progress라는 이벤트도 있습니다.

저는 둘 중에 확실하게 로드가 끝난 후에 카메라 궤도를 재설정해주기 위해 progress를 사용하겠습니다.

 

(html, css는 그대로 js만 수정합니다)

const MV_MODAL_BOX = document.querySelector('.mv-modal-box');
const MODAL_VIEWER = document.querySelector('#model-ex');
const modelOpenBtn = document.querySelector('.open-model-btn');

MODEL_VIEWER.addEventListener('progress', (e) => {
    if (e.detail.totalProgress === 1) {
        MODEL_VIEWER.cameraOrbit = '0deg 75deg 105%';
    }
});

modelOpenBtn.addEventListener('click', (e) => {
    const target = e.currentTarget;
    const productName = target.getAttribute('data-product-name');
    
    MV_MODAL_BOX.style.display = 'block';
    loadModel(productName)
});

function loadModel(name) {
    const modelSrc = `./assets/model/${name}.glb`;
    MODEL_VIEWER.setAttribute('src', modelSrc);
}

progress 이벤트 내에서 e.detail.totalProgress를 콘솔로 찍어보면 0 ~ 1까지 여러 번 찍히는 것을 알 수 있는데 진행률이 1이 되었을 때(완료) 카메라 궤도를 재설정해줬습니다.

 

camera-orbit이라는 속성입니다. 기본값은 위에 설정한 대로 '0 deg 75 deg 105%'이며 각각 theta phi radius를 나타내고 기본값 외에 다른 값 설정이 가능합니다.

 

이제 모델을 변경해보면 로드 후에 카메라 궤도가 재설정되어 처음으로 돌아가는 것을 확인할 수 있습니다.


1. 애니메이션 추가하기 및 모달 닫기

 

JS - web에 3D 모델을 띄우자! with. AR (model-viewer 사용법 2)

2022.09.13 - [개발/js] - JS - web에 3D 모델을 띄우자! with. AR (model-viewer 사용법 1) JS - web에 3D 모델을 띄우자! with. AR (model-viewer 사용법 1) 구글에서 제공하는 라이브러리인 model-viewer를 사..

waterpole.tistory.com

 

2. zoom in/out, animation toggle, full screen 기능 추가하기

 

[JS] model-viewer 사용법 3 - model control 하기 (zoom in/out, animation toggle, full screen)

이전 글 보기 (더보기 클릭) 더보기 2022.09.13 - [개발/js] - [JS] model-viewer 사용법 1 - web에 3D 모델을 띄우자! JS - web에 3D 모델을 띄우자! with. AR (model-viewer 사용법 1) 구글에서 제공하는 라이브..

waterpole.tistory.com

3. ar 활성화

 

[JS] model-viewer 사용법 4 - model AR 활성화 및 커스텀 하기

이전 글 보기 (더보기 클릭) 더보기 [JS] model-viewer 사용법 1 - web에 3D 모델을 띄우자! [JS] model-viewer 사용법 1 - web에 3D 모델을 띄우자! 구글에서 제공하는 라이브러리인 model-viewer를 사용해서 web..

waterpole.tistory.com


util, ui등 평소 개발 스타일대로 포스팅 소스의 파일을 나눠서 export/import해서 진행하는 것은 포스팅 가독성을 떨어뜨린다고 판단해서 해당 포스팅은 별도의 리팩토링 없이 한 파일에 진행됩니다.

 

피드백, 질문, 댓글 언제나 환영입니다!

감사합니다 :)

 

반응형