[물리엔진 자동차(4)]

JAMEe_·2024년 7월 4일

R3F

목록 보기
18/24

3D 오브젝트 실제 모델 적용하기

몸통 적용하기

gltfjsx
GLTF 를 선언적이고 재사용가능한 react-three-fiber jsx 컴포넌트로 변환시켜주는 도구

  • 쉬운 콘텐츠 수정 및 재사용
    모든 객체와 재질에 대한 가상 그래프를 생성하여 사용자가 3D 모델의 콘텐츠를 쉽게 수정하고 재사용할 수 있게 해줌
  • 효율적인 그래프 최적화
    생성된 그래프는 비어있는 그룹이나 불필요한 변환과 같은 요소를 제거하여 성능 향상
  • 압축 옵션 제공
    모델을 선택적으로 최대 70 ~ 90% 까지 압축시킬 수 있음

사용방법
npx gltfjsx [경로의 모델명][옵션]

옵션 명령어
--output ./car.jsx : 변환된 jsx 파일을 지정된 경로에 저장
--types : tsx 형태로 출력

glb 모델 로드 방법
기존에는 primitive 컴포넌트에 object 에 추가해주는 형식으로 구현을 했지만 ( 뭉태기 ),
이번에는 glftjsx 를 사용하여 각 mesh 에 geometry 를 모델의 부분별로 추가해주는 형식으로 구현을 했다.
그리고 바퀴는 따로 만들거기 때문에 jsx 에서 바퀴부분은 주석처리한다

크기 맞추기
우선, 가상 3D 오브젝트(물리엔진)와 모델의 크기를 맞추기 위해 모델에 leva 의 useControls 를 통해 빠르게 맞춰주기

geometry 에 args 값을 변경하여 크기를 변경할 수 있었다면
group, mesh 에서는 scale 을 사용하여 전체적인 크기를 변경할 수 있음


바퀴 적용하기

차체의 jsx 에서 주석처리했던 바퀴부분을 불러와서 적용시킬 것이다
한 바퀴로 4개의 바퀴를 설정해줄것이기 때문에
가져온 바퀴의 반대 방향의 바퀴 디자인을 보여주기 위해서
group 의 rotation y 축을 설정해줄것이다

export default function Wheel({ wheelRef, radius, leftSide }) {
  const { nodes, materials } = useGLTF("/assets/models/car_taxi.glb");
  return (
    <group ref={wheelRef} scale={radius * 10}>
      <group rotation={leftSide ? [0, -Math.PI, 0] : [0, 0, 0]}>
        <mesh
          geometry={nodes.Car01_2_WhFL002_0.geometry}
          material={materials.mt_PalleteBR}
          rotation={[-1.576, 0, 0]}
          scale={0.32}
        />
      </group>
    </group>
  );
}

여러 차량을 구현하기 위한 엔진 알아보기

useRaycastVehicle 에 선언한 wheelInfos 에 대한 정보들이다

 const wheelInfo = {
    // 이 속성들을 어떻게 주냐에 따라 차량이 달라진다
    radius,
    directionLocal: [0, -1, 0], // 바퀴의 로컬 방향 벡터 (세계 좌표계 기준)
    axleLocal: [1, 0, 0], // 바퀴의 로컬 회전 축 벡터 (세계 좌표계 기준)
    suspensionStiffness: 25, // 서스펜션 강성 (낮을수록 부드럽고 높을수록 강하게 튕김 )
    suspensionRestLength: 0.1, // 서스펜션 초기 길이 (미터)
    frictionSlip: 5, // 타이어 마찰력
    dampingRelaxation: 1, // dampingCompression 과 함께 낮게 주면 차량 흔들림이 심함
    dampingCompression: 1, // 댐핑 관련 매개변수 (낮을수록 진동이 심하게, 높을수록 안정적)
    maxSuspensionForce: 100000, // 최대 서스펜션 힘 (넘어지지 않도록 하는데 사용)
    rollInfluence: 0.01, // 차량의 기울기에 따른 바퀴의 롤링 영향 (낮을수록 안정적, 높을수록 미끄러움)
    maxSuspensionTravel: 0.3, // 최대 서스펜션 이동 거리 (미터)
    customSlidingRotationalSpeed: -30, // 사용자 정의 슬라이딩 회전 속도 (라디안/초, 음수 값은 반시계 방향 회전)
    useCustomSlidingRotationalSpeed: true, // 사용자 정의 슬라이딩 회전 속도 사용 여부
    sleepSpeedLimit: 0.01, // 슬립 상태에서 자동으로 차량을 꺼냄 (낮을수록 민감, 높을수록 허용)
};

const wheelInfos = [
    {
      ...wheelInfo,
      // 휠의 위치 정해줌 앞바퀴
      chassisConnectionPointLocal: [-width * 0.65, height * 0.3, front],
      // 차량의 핸들링과 물리 엔진 내에서의 바퀴 동작을 정확하게 시뮬레이션
      // 앞바퀴와 뒷바퀴의 역할이 다르기 때문에, 이 속성을 올바르게 설정하는 것이 중요
      isFrontWheel: true,
    },
    {
      ...wheelInfo,
      chassisConnectionPointLocal: [width * 0.65, height * 0.3, front],
      isFrontWheel: true,
    },
    {
      ...wheelInfo,
      // 뒷바퀴
      chassisConnectionPointLocal: [-width * 0.65, height * 0.3, -front],
      isFrontWheel: false,
    },
    {
      ...wheelInfo,
      chassisConnectionPointLocal: [width * 0.65, height * 0.3, -front],
      isFrontWheel: false,
    },
];

나무와 공에 모델 적용하기

자동차와 마찬가지로 jsx 로 변환하여 적용
useBoxuseSphere 를 사용하여 가상 3D 오브젝트를 만들고
모델을 그 크기에 맞게 잘 조정해주기

텍스트 Scene 에 추가하기

drei 의 Text 컴포넌트 사용하여 3D 환경에 Text 주입 가능.
font 를 적용시켜주기 위해선 일반적인 웹에서 사용하는
ttf, woff.. 가 아닌 json 형식으로 되어야함.
원하는 폰트를 json 형식으로 변환시켜 사용하면 된다.

Text 컴포넌트 (2D)

<Text
  // 색상
  color={'white'}
  // json 형식의 폰트 경로
  font={'/pretendard.json'}
  // 웹에서는 글꼴 데이터를 로딩하는 동안 텍스트가 표시 되지 않는 문제가 발생할 수 있음
  // 우선적으로 로드할 글꼴을 선언. 문자(children)와 동일하게 선언하면 가장 빠름
  characters=""
  >
  {문자}
  <meshNormalMaterial/>
</Text>

Text3D 컴포넌트 (3D)

※ font 와 meshMaterial 필수

<Text3D
  // 필수
  font={'/pretendard.json'}
  // 글자 크기
  size={0.5}
  // 글자 간격
  letterSpacing={0.15}
  // 글자 z축 크기
  height={0.02}
  // 글자 경계선 부드럽게 (글자 두께에 영향)
  bevelEnabled={true}
  // 경계선의 두께
  bevelOffset={0.001}
  // 경계선의 크기
  bevelSize={0.001}
  // 경계선의 z축 크기
  bevelThickness={0.01}
  >
  {문자}
  // 필수
  <meshNormalMaterial/>
</Text3D>
profile
안녕하세요

0개의 댓글