on
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