THREE.JS 사용해보기 1에서 설명한 three.js의 구성요소인 Scene을 이용한 공간구성에 대해 설명합니다!
GIS DEVELOPER님의 유튜브 영상을 보고 작성하였습니다. 정말 잘 설명해주십니다. 감사합니다!
3D Object가 3차원 공간 상에 놓여지기 위해 필요한 값으로는 위치, 회전, 크기 값이 있다.
position : xyz축에 대한 위치값(default 0)
rotation : xyz축에 대한 회전값(default 0)
scale : xyz축에 대한 크기의 배수값(default 1이고 1 값은 원래 크기를 의미)
position, rotation, scale은 4x4 크기의 행렬 정보로 변환된다.
three.js의 xyz 좌표 축 구성은 아래 그림과 같다.
(feat. xyz 공간상에 3D 객체 여러개 구성하기)
코드 리뷰에 앞서 scene graph를 도식화한다. 이 표에 따라 구현하면 된다.
퀄리티를 높이기 위하여 천체들의 texture를 이미지로 지정해주었다.
_setupModel() {
// Object3D 타입의 solarSystem 객체 생성, scene에 추가
const solarSystem = new THREE.Object3D();
this._scene.add(solarSystem);
// 구 모양 geometry 생성
const radius = 1;
const widthSegments = 12;
const heightSegments = 12;
const sphereGeometry = new THREE.SphereGeometry(
radius,
widthSegments,
heightSegments
);
//텍스쳐 매핑을 위해 TextureLoader 클래스 선언
const loader = new THREE.TextureLoader();
// 태양 재질 생성, 콜백함수 지정
const sunMaterial = new THREE.MeshBasicMaterial({
map: loader.load(
"./img/8k_sun.jpg",
undefined,
undefined,
function (err) {
alert("Error");
}
),
});
// sunMesh 객체 생성
const sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial);
// 원래 지오메트리 크기보다 3배의 크기로 표시
sunMesh.scale.set(3, 3, 3);
solarSystem.add(sunMesh);
// Object3D 타입의 earthOrbit 객체 생성
const earthOrbit = new THREE.Object3D();
// earthOrbit 객체를 solarSystem의 자식으로 추가함
solarSystem.add(earthOrbit);
// 지구 재질 생성
const earthMaterial = new THREE.MeshBasicMaterial({
map: loader.load(
"./img/8k_earth_daymap.jpg",
undefined,
undefined,
function (err) {
alert("Error");
}
),
});
const earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial); // earthMesh 객체 생성
earthOrbit.position.x = 10; // 태양에서 x축으로 거리 10만큼 떨어진 위치로 지구 배치
earthOrbit.add(earthMesh); // earthMesh 객체를 earthOrbit의 자식으로 추가
const moonOrbit = new THREE.Object3D(); // Object3D 타입의 moonOrbit 객체 생성
/*
moonorbit은 earthOrbit의 자식이므로, earthOrbit 기준으로 x축 거리 2만큼 떨어진 곳에 배치됨
태양 관점에서 보면 moonOrbit은 거리 12만큼 떨어짐
*/
moonOrbit.position.x = 2;
earthOrbit.add(moonOrbit); // 생성한 moonOrbit 객체를 earthOrbit의 자식으로 추가함
// 달 재질 생성
const moonMaterial = new THREE.MeshBasicMaterial({
map: loader.load(
"./img/8k_moon.jpg",
undefined,
undefined,
function (err) {
alert("Error");
}
),
});
// moonMesh 생성
const moonMesh = new THREE.Mesh(sphereGeometry, moonMaterial);
moonMesh.scale.set(0.5, 0.5, 0.5); // 원래 구 반지름 절반 크기로 달이 생성됨
moonOrbit.add(moonMesh); // moonMesh를 moonOrbit의 자식으로 추가
// 객체를 다른 메서드에서 참조할수 있도록함
this._solarSystem = solarSystem;
this._earthOrbit = earthOrbit;
this._moonOrbit = moonOrbit;
}
천체의 공전/자전을 위해 다음 코드를 추가한다.
update(time) {
time *= 0.001; // second unit
// solarSystem은 y축에 대해 계속 회전
this._solarSystem.rotation.y = time / 2;
// 지구의 자전
this._earthOrbit.rotation.y = time * 2;
// 달의 자전
this._moonOrbit.rotation.y = time * 5;
}
결과: