THREE.JS Scene Graph

15646 단어 three.jsSceneScene

THREE.JS 사용해보기 1에서 설명한 three.js의 구성요소인 Scene을 이용한 공간구성에 대해 설명합니다!
GIS DEVELOPER님의 유튜브 영상을 보고 작성하였습니다. 정말 잘 설명해주십니다. 감사합니다!

Object3D 속성

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;
	}

결과:

좋은 웹페이지 즐겨찾기