3D 이미지인 GLTF를 이용해서 여러 구도에서 그걸 봐야할 때 어떻게 해야할까요?

juunini·2022년 2월 6일
1
post-thumbnail

그게 뭐야 골치아파 그냥 사진찍어줘 ㄷㄷ

대체 뭔소리야?

GLTF? GLB?

Blender로 만든 3D 오브젝트를 GLB로 내보낸 뒤 그걸 읽어서 화면에 보여주는겁니다.
GLB를 쉽게 보려면 glTF Viewer에서 보시면 됩니다.

그래서 뭘 하려는거야?

여우 glb는 https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/Fox/glTF-Binary 에서 받았습니다.

이런 식으로 여러 구도에서 보고싶은겁니다.
그런데, A-Frame을 이용해서 저 여우 GLB를 불러오면

이런 화면이 나옵니다. 나무?
W A S D 키를 이용해 움직이면 되는데, 불러오자마자 사용자에게 위의 구도들에서 보여줄 수가 없습니다.
곧장 보여주려면 카메라에 좌표값을 넣어줘야 하죠.

아, 말만 들어도 너무 어렵다. 이런거 왜 해요?

3D를 웹으로 표현하려면 필요합니다. 물론 2D웹만 만든다면 필요 없지요.
하지만 많은 사람들이 웹으로 3D를 표현하는데 관심이 많을거라 생각합니다.
그리고 저는 그리 어렵지 않게 이런걸 만드는 방법을 공유하고 있어요.

그래서 좌표값은 어떻게 구함?

아래 코드를 쓰면 얻을 수 있습니다.

import { useEffect, useState } from 'react';
import AFRAME from 'aframe';
import { AssetItem, Assets, Camera, GLTFModel, Scene } from '@belivvr/aframe-react';

interface Vec3 {
  x: number;
  y: number;
  z: number;
}

function App() {
  const [position, setPosition] = useState<Vec3>({ x: 0, y: 0, z: 0 });
  const [rotation, setRotation] = useState<Vec3>({ x: 0, y: 0, z: 0 });

  useEffect(() => {
    AFRAME.registerComponent('camera-listener', {
      tick() {
        const cameraEl = this.el;
        const currentPosition = cameraEl.getAttribute('position');
        const currentRotation = cameraEl.getAttribute('rotation');
        const { x, y, z } = currentPosition;
  
        setPosition({ x, y, z });
        setRotation(currentRotation);
      },
    });
  }, []);
  
  return (
    <Scene
      renderer={{
        colorManagement: true,
        physicallyCorrectLights: true,
      }}
    >
      <div
        style={{
          position: 'absolute',
          zIndex: 1000,
          top: 0,
          right: 0,
        }}
      >
        {`position: ${position.x.toFixed(2)} ${position.y.toFixed(2)} ${position.z.toFixed(2)}`}
        <br />
        {`rotation: ${rotation.x.toFixed(2)} ${rotation.y.toFixed(2)} ${rotation.z.toFixed(2)}`}
      </div>

      <Camera
        camera-listener
        wasdControls={{ acceleration: 500, fly: true }}
      />

      <Assets>
        <AssetItem src="/Fox.glb" id="fox" />
      </Assets>
      <GLTFModel src="#fox" />
    </Scene>
  );
}

export default App;

오 쩐다! 그래서 위에 있는 숫자를 집어넣으면 되나요?

맞습니다. 위 숫자를 카메라의 좌표에 입력하면 유저는 화면이 로딩되자마자 해당 좌표에서 여우를 볼 수 있습니다.

import 'aframe';
import { AssetItem, Assets, Camera, GLTFModel, Scene } from '@belivvr/aframe-react';

function App() {
  return (
    <Scene
      renderer={{
        colorManagement: true,
        physicallyCorrectLights: true,
      }}
    >
      <Camera
        wasdControls={{ enabled: false }}
        lookControls={{ enabled: false }}
        position={{ x: 55.27, y: 72.53, z: 84.33 }}
        rotation={{ x: -33.92, y: 46.52, z: 0 }}
      />

      <Assets>
        <AssetItem src="/Fox.glb" id="fox" />
      </Assets>
      <GLTFModel src="#fox" />
    </Scene>
  );
}

export default App;

근데 왜 wasd랑 lookControls는 막아요?

W A S D 키는 굳이 막을 필요가 없지만, lookControls 를 막지 않으면 카메라의 rotation이 적용되지 않습니다.
lookControls이 적용된 상태에서 rotation에 값을 입력해도 x: 0, y: 0, z: 0 으로 고정돼요. 그래서 막은겁니다.
고개는 움직일 수 없는데 몸만 움직이면 그것도 이상한 느낌일테니 둘 다 못하게 막았습니다.

그럼 안막고 하려면 어떻게 해야돼요?

그럼 여우에다가 rotation을 줘서 돌려야겠지요?
제가 그건 아직 안해봐서 어떻게 해야할지 연구를 안해봤네요 ㅋㅋㅋㅋㅋㅋㅋ

profile
지상 최강의 개발자 쥬니니

1개의 댓글

comment-user-thumbnail
2022년 3월 1일

감사합니다

답글 달기