Link Search Menu Expand Document

FBX

이 튜토리얼은 Three.js를 이용한 3D 기반의 ARWebApp을 만드는 방법을 설명합니다.

Table of contents

  1. FBX
  2. 준비사항
    1. three.js
    2. Letsee Web AR SDK
  3. 코드 설명
    1. js 임포트
    2. 증강을 위한 Entity 설정
    3. Web AR SDK 실행 및 three.js
    4. Mixer 생성
    5. 라이트 생성
    6. 3D 오브젝트 로드와 render
    7. three.js 코드
  4. What you should see
  5. Final code
  6. Demo

FBX

3D 장면을 설명하는 방법으로 3D 매쉬, 캐릭터, 조명 또는 카메와 같은 요소를 나타내는 노드로 구성된 계층형 장면 그래프를 포함합니다.

준비사항

three.js

Three.js는 웹페이지에 3D 객체를 쉽게 렌더링하도록 도와주는 자바스크립트 3D 라이브러리입니다. 대부분의 경우 Three.js는 3D 객체를 렌더링하는 데 WebGL을 사용합니다. 때문에 Three.js = WebGL이라고 착각하기 쉽죠. 하지만 WebGL은 점, 선, 삼각형만을 그리는 아주 단순한 시스템입니다. WebGL로 직접 무언가를 만들려면 상당히 많은 양의 코드를 짜야 하죠. 만약 씬(scenes), 광원, 그림자, 물체, 텍스처 등 3차원 세계를 구현한다면 머리도 꽤 복잡하겠거니와 코드 자체도 굉장히 복잡할 겁니다. Three.js는 이런 3D 요소들의 처리를 도와 직관적인 코드를 짤 수 있도록 해줍니다. threejs fundamentals

아래의 예제는 three.js의 FBX Loader 예제를 Letsee Web AR SDK에 맞추어 변환한 것 입니다.
3D파일을 로드하기 위한 스크립트, 3D 오브젝트 파일등은 three.js의 github에서 다운로드 받을 수 있습니다.

three.js는 r120 버전을 기준으로 설명합니다.FBXLoader.js, inflate.min.js는 r105 버전을 기준으로 설명합니다.

Letsee Web AR SDK

Web AR 어플리케이션에서 사용할 마커 이미지와 엔터티 설정 파일이 필요합니다. 아래 예제에서 사용한 마커와 엔터티 파일은 Letsee에서 제공하는 샘플 입니다.

Letsee Web AR SDK를 사용하기 위해서는 SDK파일과 appKey가 필요합니다. SDK 파일은 cdn을 통해 제공됩니다.
인증을 위한 appKey는 이곳을 확인해 주시기 바랍니다.


코드 설명

js 임포트

Letsee Web AR SDK와 three.js를 위한 javascript를 임포트 합니다.
three.js의 FBX loading sample를 참고하여 FBXLoader.jsinflate.min.js를 준비합니다.

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.js"></script>
<script src="js/loaders/r105/FBXLoader.js"></script>
<script src="js/lib/r105/inflate.min.js"></script>
<script src="https://developer.letsee.io/api/webar?key=YOUR_APP_KEY"></script>

증강을 위한 Entity 설정

증강할 대상을 addTarget 이벤트의 매개변수로 설정합니다.

letsee.addTarget('letsee-marker.json').then(entity => {})

Web AR SDK 실행 및 three.js

letsee의 init 이벤트 실행, ready 이벤트의 callback에 start 이벤트를 등록하여 어플리케이션을 실행합니다.

letsee.ready(() => {
  letsee.start();
  letsee.addTHREE(THREE).then(obj => {
    renderer = obj.renderer;
    scene = obj.scene;
    initWorld(obj);
  })
});
letsee.init();

Mixer 생성

애니메이션을 위한 mixer를 생성합니다.

let mixer;

라이트 생성

렌더링을 위한 라이트를 생성합니다.

let light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, -95, 120);
scene.add(light);

3D 오브젝트 로드와 render

FBX Loader를 사용하여 3D 오브젝트를 로드하고 증강대상과의 정합을 위해 entity에 등록 후, scene에 entity를 등록합니다. 프레임 단위로 render합니다.

letsee.addTarget('letsee-marker.json').then(entity => {
    let toystory = entity;
    let mesh, mixer;
    
    const loader = new THREE.FBXLoader();
    loader.load('models/fbx/Samba Dancing.fbx', function (object) {
      object.position.set(0, -95, 50);
      object.visible = true;
      object.scale.setScalar(1);
    
      // Create custom animation clips
      if (object.animations.length > 0) {
        mixer = new THREE.AnimationMixer(object);
        const action = mixer.clipAction(object.animations[0]);
        action.play();
      } else console.error(`Model [${object.name}] does not have animation.`);
    
      mesh = object;
      toystory.add(mesh);

      // Add entity to scene
      scene.add(toystory);
    
      // Render all
      const renderAll = async function () {
        requestAnimationFrame(renderAll);
        if (mixer) {
          let delta = clock.getDelta();
          mixer.update(delta);
        }
        await letsee.threeRenderer().update(); // Engine mainLoop 수행
        const camera = letsee.threeRenderer().getDeviceCamera(); // 매 프레임마다 카메라 얻어옴.
        renderer.render(scene, camera); // Three.js 화면 갱신
      };
      renderAll();
    });
});

three.js 코드

FBX loading sample을 바탕으로한 3d 오브젝트 증강 예제 입니다.


What you should see






Final code

소스 코드는 이곳에서 다운받을 수 있습니다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Letsee WebAR Demo</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.js"></script>
  <script src="js/loaders/r105/FBXLoader.js"></script>
  <script src="js/lib/r105/inflate.min.js"></script>
  <script src="https://developer.letsee.io/api/webar?key=YOUR_APP_KEY"></script>
</head>
<body>
  <script>
    let scene;
    let renderer;
    let clock = new THREE.Clock();

    letsee.ready(() => {
      letsee.start();
      letsee.addTHREE(THREE).then(obj => {
        renderer = obj.renderer;
        scene = obj.scene;
        initWorld(obj);
      })
    });
    letsee.init();

    const initWorld = (obj) => {
      let light = new THREE.DirectionalLight(0xffffff);
      light.position.set(0, -95, 120);
      scene.add(light);

      letsee.addTarget('letsee-marker.json').then(entity => {
        let toystory = entity;
        let mesh, mixer;

        const loader = new THREE.FBXLoader();
        loader.load('models/fbx/Samba Dancing.fbx', function (object) {
          object.position.set(0, -95, 50);
          object.visible = true;
          object.scale.setScalar(1);

          // Create custom animation clips
          if (object.animations.length > 0) {
            mixer = new THREE.AnimationMixer(object);
            const action = mixer.clipAction(object.animations[0]);
            action.play();
          } else console.error(`Model [${object.name}] does not have animation.`);

          mesh = object;
          toystory.add(mesh);

          // Add entity to scene
          scene.add(toystory);

          // Render all
          const renderAll = async function () {
            requestAnimationFrame(renderAll);
            if (mixer) {
              let delta = clock.getDelta();
              mixer.update(delta);
            }
            await letsee.threeRenderer().update(); // Engine mainLoop 수행
            const camera = letsee.threeRenderer().getDeviceCamera(); // 매 프레임마다 카메라 얻어옴.
            renderer.render(scene, camera); // Three.js 화면 갱신
          };
          renderAll();
        });
      });
    }
  </script>
</body>
</html>

Demo

모바일 디바이스로만 확인 가능합니다.
Demo link