-
Three.js module 활용 - (4) Scene GraphThree.js 2022. 9. 26. 16:48
[이전 글]
Three.js module 활용 - (3) Geometry 마무리
[이전 글] Three.js module 활용 - (2) Geometry [이전 글] https://chaeng03.tistory.com/13 Three.js module 활용 - (1) Basic [이전 글] https://chaeng03.tistory.com/12 Three.js 입문기 해당 게시글은 2022...
chaeng03.tistory.com
해당 게시글은 2022.05.11에 깃허브로 작성되었으며
아래 유튜브 강의 영상을 수강하며 공부한 내용을 기재했습니다.
1. Object 3D
Mesh는 Line, Points와 같이 Object 3D의 파생 CLASS인데
3D Object가 3차원 공간 상에 놓이기 위해 다음과 같은 값이 필요하다.
- position
x, y, z축에 대한 위치값으로 기본값은 모두 0이다.
- rotation
x, y, z축에 대한 회전값으로 기본값은 모두 0이다.
- scale
x, y, z축에 대한 크기의 배수값으로 기본값은 모두 1이다.이번 시간에는 위 세가지 값에 변화를 주며 3차원 공간에 3D Object 여러개를 두는 방법에 대해 알아보자.
이전에 생성했던 01_basic.html, css, js 파일들을 복사하여 붙여넣기한 후 파일명을 03_scenegraph로 변경하고
그에 맞춰 03_scenegraph.html에서 css와 js를 import하는 부분을 변경된 파일명에 맞춰 수정해보자.
2. 태양 생성
이어서 03_scenegraph.js에서 3D Object를 정의하는 _setupModel 함수 내부 코드를 제거하고 다음과 같이 작성하여 태양을 만들어보자.
반지름을 1로 가지고 가로, 세로 분할 개수가 12인 구를 SphereGeometry라는 이름으로 생성했다.
이 SphereGeometry는 태양뿐만 아니라 지구와 달에게도 적용할 것이기에 변수로 생성한 것이다.
// 03_scenegraph.js _setupModel() { const solarSystem = new THREE.Object3D(); this._scene.add(solarSystem); const radius = 1; const widthSegments = 12; const heightSegments = 12; const SphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments); const sunMaterial = new THREE.MeshPhongMaterial({ emissive: 0xffff00, flatShading: true}); const sunMesh = new THREE.Mesh(SphereGeometry, sunMaterial); sunMesh.scale.set(3, 3, 3); solarSystem.add(sunMesh); }
이어서 태양의 Material을 생성하는데 색상은 ffff00(yellow)으로 한다.
앞서 생성한 SphereGeometry와 sunMaterial를 sunMesh에 대입함으로써 태양을 생성한다.
태양은 SphereGeometry를 기준으로 3배의 크기를 갖도록 하고 이를 최상위 Mesh인 solarSystem에 추가한다.
그러고 페이지를 보면 아무것도 안 보이고 까만 화면만 보이는데 이는 camera가 태양 내부에 위치해있기 때문이다.
camera의 position.z를 50으로 변경해보자.
camera.position.z = 50;
그럼 아래와 같이 노란색 구인 태양이 보이게 된다.
3. 지구 생성
이어서 다음 코드를 작성함으로써 지구를 생성해보자.
지구 Mesh를 담을 earthOrbit 을 생성하여 최상위 Mesh인 solarSystem에 추가하고
태양과 마찬가지로 지구에 대한 Material 생성 후 이를 earthMesh에 대입함으로써 지구를 생성한다.
생성된 지구인 earthMesh는 앞서 생성한 earthOrbit에 추가하여 solarSystem에 추가되도록 하고
지구의 position.x를 10으로 설정함으로써 태양으로부터 수평으로 10만큼 떨어져있게 설정한다.
태양이 기준이 될 수 있는 이유는 최상위 Mesh인 solarSystem에 바로 태양이 속해있기 때문이다.
const earthOrbit = new THREE.Object3D(); solarSystem.add(earthOrbit); const earthMaterial = new THREE.MeshPhongMaterial({ color: 0x2233ff, emissive: 0x112244, flatShading: true}); const earthMesh = new THREE.Mesh(SphereGeometry, earthMaterial); earthOrbit.position.x = 10; earthOrbit.add(earthMesh);
코드를 작성하고 화면을 보면 태양으로부터 10만큼 떨어져있는 지구 를 볼 수 있다.
지구가 태양보다 상대적으로 작은 이유는 앞서 태양의 scale을 설정할 때 기준 크기로부터 3배로 설정했기 때문이다.
4. 달 생성
이어서 달을 만들어보자.
지구와 마찬가지로 달 Mesh를 담을 moonOrbit을 생성하여 earthOrbit에 추가한다.
이 이유는 달이 지구를 중심으로 공전을 하기에 지구의 자식 요소로 넣은 것이다.
const moonOrbit = new THREE.Object3D(); moonOrbit.position.x = 2; earthOrbit.add(moonOrbit); const moonMaterial = new THREE.MeshPhongMaterial({ color: 0x888888, emissive: 0x222222, flatShading: true}); const moonMesh = new THREE.Mesh(SphereGeometry, moonMaterial); moonMesh.scale.set(0.5, 0.5, 0.5); moonOrbit.add(moonMesh);
이어서 달의 position.x를 2로 설정함으로써 지구보다는 수평으로 2만큼, 태양보다는 수평으로 12만큼(지구-10 + 달-2) 떨어져있게 하고
달의 Material을 생성하고 이를 moonMesh에 대입함으로써 달을 생성한다.
달의 scale을 기준 크기로부터 0.5배로 설정하여 작게 만들고 moonOrbit에 추가하여 earthOrbit을 거쳐 solarSystem에 속하게 한다.
코드를 작성하고 화면을 보면 달이 생성된 것을 볼 수 있다.
5. 애니메이션
이제 태양은 자전을, 지구는 태양을 중심으로 공전과 자전을, 달은 지구를 중심으로 공전을 하게 만들어보자.
우선 생성한 태양과 지구, 달을 update 함수에서 사용하기 위해서는 이전과 같이 this를 이용하여 연결해줘야 한다.
_setupModel 함수 내에 아래와 같은 코드를 작성하자.
this._solarSystem = solarSystem; this._earthOrbit = earthOrbit; this._moonOrbit = moonOrbit;
좀 더 가까이서 확인할 수 있게 camera의 position.z값을 조정해보자.
// _setupCamera camera.position.z = 15;
이제 update 함수에 아래와 같이 작성함으로써 태양과 지구와 달을 회전시켜보자.
update(time){ time *= 0.001; // second unit this._solarSystem.rotation.y = time / 2; this._earthOrbit.rotation.y = time * 2; this._moonOrbit.rotation.y = time * 5; }
가로 방향으로 돌리는데 왜 x가 아닌 y를 쓰는가 의문이 들었는데
Three.js에서rotation의 의미는 해당축으로 막대기를 꽂고 회전시킨다는 의미로 이해하면 된다.
이렇게 Object 3D를 이용하여 scene Graph를 생성해봤다.
다음엔 이제까지 사용해봤던 Material에 대해 자세히 알아보는 시간을 가져보자.
[Three.js module 활용 - (4) Scene Graph 전체 코드]
GitHub - rlacodud/UID
Contribute to rlacodud/UID development by creating an account on GitHub.
github.com
'Three.js' 카테고리의 다른 글
Three.js module 활용 - (6) Texture Material (0) 2022.09.26 Three.js module 활용 - (5) Material (1) 2022.09.26 Three.js module 활용 - (3) Geometry 마무리 (1) 2022.09.26 Three.js module 활용 - (2) Geometry (1) 2022.09.26 Three.js module 활용 - (1) Basic (0) 2022.09.26