Do it 3d! - 회전하는 3d 큐브

Do it 3d! - 회전하는 3d 큐브

Do it 3d! - 회전하는 3d 큐브

빡빡한 스케줄의 부트캠프가 끝난 뒤 풀어질대로 풀어져서...

프로그래밍에 대한 권태기가 찾아왔다ㅋㅋㅋ 이론만 하고..

그래서 재밌는걸 하면 다시 재밌어질 것 같아서! 하던걸 모두 보류하고 3d 라이브러리인 THREE.js를 가지고 놀아보았다!

https://github.com/NariP/3d

결과

회전한는 초록색 정육면체가 만들어졌다!

전체 코드 보러가기

1. Three.js 불러오기

https://www.npmjs.com/package/three

// 설치

yarn add three

// 불러오기

import * as THREE from 'three'

Three.js 를 사용하여 무언가 해보려면 scene, camera, renderer 이렇게 세가지가 필요하다.

나는 카메라를 통해 보여지는 씬을 렌더러를 통해서 렌더한다고 이해를 하였다.

3d 툴을 만져보긴 했어서 이해하는데 조금 수월했던 것 같다..!

2. 씬 생성

const scene = new THREE.Scene(); // 씬 생성

3. 카메라 생성

https://threejsfundamentals.org/threejs/lessons/kr/threejs-cameras.html

const camera = new THREE.PerspectiveCamera(75, width / height, 1, 1000) // camera 생성 camera.position.z = 5

PerspectiveCamera: 원근 카메라, 보통 이걸 사용한다고 함, 아래의 요소들로 렌더링되는 공간 범위를 만든다

PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )

fov : field of view 시야각

aspect: 캔버스의 가로 세로 비율

near, far: 카메라 앞에 렌더링 되는 공간범위

설명은 링크에 정말 자세하게 잘 되어있다!

width와 height의 경우 윈도우의 innerwidth와 innerheight를 많이 사용하는 것 같다

어느정도의 숫자를 넣어야할지 감이 오지 않는다면 튜토리얼의 숫자를 그대로 따라 친 다음에 숫자를 조절해보는 것도 괜찮은 방법 같다!

camera position의 경우 x, y, z를 동시에 변경하고 싶을 때는

camera.position.set(x, y, z) 를 사용하는게 좀 더 편하다

4. 렌더러 생성

const renderer = new THREE.WebGLRenderer(); renderer.setSize(width, height) viewerRef.current.appendChild(renderer.domElement) // viewerRef 요소의 자식으로 추가

위 코드는 동적으로 캔버스 요소를 문서에 삽입하는 방법을 사용하였다.

아래 코드처럼 Three.js에 canvas 요소를 넣어주면

canvas 요소 참조 -> 입력한 데이터를 바탕으로 canvas에 그리기 순서로 진행됩니다

const canvas = document.querySelector('#c'); const renderer = new THREE.WebGLRenderer({canvas});

5. 오브젝트 생성과 씬에 오브젝트 추가

const geometry = new THREE.BoxGeometry(1,1,1); const material = new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: true}) const cube = new THREE.Mesh(geometry, material); scene.add(cube) // 씬에 추가

width, height, depth 속성을 입력하여 정육면체를 생성 -> material 생성 -> 정육면체와 material을 결합하여 3d 오브젝트 생성

-> 씬에 추가

3d 툴에서 오브젝트를 생성할 때 일단 도형(큐브 또는 기타 등등)을 추가한 후 material을 입히는데 이것과 비슷한 동작이니 똑같이 이해하면 될 것 같다.

결과 영상엔 wireframe 속성을 설정해주지 않아서 다르게 보이는데

wireframe: true 를 해주면 아래처럼 보인다

오브젝트를 만든 후 씬에 추가하지 않으면 렌더되지 않으므로 꼭 추가해주자!

6. 렌더하기

renderer.render(scene, camera);

7. 애니메이션 추가

https://developer.mozilla.org/ko/docs/Web/API/window/requestAnimationFrame

const animate = () => { renderer.render(scene, camera); cube.rotation.x += 0.01; cube.rotation.y += 0.01; requestAnimationFrame(animate); }; animate();

마치며..

좀 더 그럴싸한 정육면체를 만들고 싶다면 광원을 추가하면 된다!(여기서는 추가하지 않았다!)

광원을 추가하게 되면 명암이 생기니 좀 더 3d 스럽게 표현이 될 것이다.

역시 재밌는 것을 하니 재밌지만

글로 옮기는 게 구현하는 것보다 시간이 오래 걸려서 다음 포스팅이 있을지는 모르겠다!

다음 포스팅이 있다면 주제는 회전하는 지구(스카이박스, 재질 입히기)다.

왜냐면 이미 구현해놓았기 때문에! 선구현 후포스팅ㅎㅎ

from http://shu-shu-bear.tistory.com/26 by ccl(A) rewrite - 2021-09-26 20:27:40