일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 백준
- Flutter
- HTML
- JavaScript
- 큐
- 리액트
- 오블완
- CSS
- 나만무
- 코드트리
- 크래프톤 정글
- Java
- 사이드프로젝트
- 알고리즘
- 시스템콜
- TiL
- 티스토리챌린지
- 자바스크립트
- Vue.js
- 4기
- 스택
- 소켓
- defee
- 자바
- 핀토스
- pintos
- corou
- 크래프톤정글
- userprog
- 모션비트
- Today
- Total
미새문지
크래프톤 정글 week13, day99 - threeJs 강의1 구현 본문
이전에 url로 올린 강의 영상을 보고 three.js를 학습했다.
아직 강의 영상 8개 더 남아있긴 한데 일단 영상 보면서 코드를 따라 쳤기 때문에 이 부분이라도 좀 복기를 하려고 한다.
먼저 threeJs란?
WebGL을 사용해 3D그래픽을 웹 브라우저에서 렌더링하기 위한 자바스크립트 라이브러리이다. WebGL은 웹에서 복잡한 계산이나 3D 그래픽 처리를 위해 설계되었다.
WebGL은 직접 사용할 경우 매우 복잡하기 때문에 처음 사용하기가 힘든데, 이러한 복잡성을 추상화하여, 개발자들이 쉽게 3D 컨텐츠를 만들어 웹에 보여줄 수 있게 하는게 threeJs 라이브러리이다.
threeJs를 설치하려면 해당 명령어를 터미널에 입력해야 한다.
npm i three
npm install three
둘 중 어느걸 써도 같은 명령어이며 yarn 명령어는 써본적이 없어서 패스
threeJs를 쓰려면 본체 설치 말고도 모듈을 더 설치해야 한다.
- react-three-fiber
- react-three/drei
R3F라고 불리는 react-three-fiber는 3D 컨텐츠를 더 간단하고 직관적으로 생성 및 관리 해주는 라이브러리이다.
threeJs의 객체 생성이나 관리 프로세스를 간소화 할 수 있어 익숙한 방식으로 3D 컨텐츠를 개발할 수 있게 해준다.
react-three/drei는 R3F를 위한 유틸리티와 높은 수준의 추상화를 제공하는 라이브러리이다. 이 모듈도 마찬가지로 threeJs 개발을 쉽고 효율적으로 만들기 위해 확장 기능과 추가 컴포넌트 등으로 구성되어 있다.
이 라이브러리들을 사용하면 반복적인 코드를 줄이고 3D 개발에 있어 직관적인 접근 방식이 가능하기 때문에 설치해야 한다.
threeJs를 설치하면 처음 사용하는 코드가 <Canvas></Canvas>인데 이 Canvas의 구성 요소는 Renderer, Scene, Camera로 구성되어 있다.
Scene은 3D장면을 의미하는데, 3D모델, 조명, 카메라로 구성되어 있다.
Camera는 Canvas가 카메라를 자동 생성해주는데 카메라로 보는 시점에 따라 다양하게 연출될 수 있기 때문에 매우 중요하다.
Renderer는 Scene과 Camera를 이용해 3D를 렌더링해주는 객체이다.
코드를 작성하면 R3F에서 Canvas를 작성해줘야 한다.
<Canvas camera={{near: 3.5, far: 6}} style={{width: '100%', height: '100vh'}}>
<MyElement3D3 />
</Canvas>
현재 학습하고 있는 코드를 가져왔는데 이런식으로 Canvas에 camera 기능을 사용해서 컴포넌트를 묶은걸 볼 수 있다.
처음 학습한 코드는 3D Scene을 생성하는 코드이다. 한 줄씩 뜯어보자.
import { OrbitControls } from "@react-three/drei";
import { useFrame } from "@react-three/fiber";
import { useRef } from "react"
import { Mesh } from "three"
import * as THREE from "three"
const Element3D = () => {
const refMesh = useRef<Mesh | null>(null);
useFrame((state, delta) => {
if(refMesh.current != null) {
refMesh.current.rotation.z += delta
}
})
return (
<>
<directionalLight position={[1, 1, 1]} />
<axesHelper scale={10} />
<OrbitControls />
<mesh ref={refMesh}
position-y={2}
rotation-z={THREE.MathUtils.degToRad(45)}
scale={[2, 1, 1]}
>
<boxGeometry />
<meshStandardMaterial
color="#e67e22"
opacity={0.5}
transparent={true}
/>
<axesHelper />
<mesh
scale={[0.1, 0.1, 0.1]}
position-y={2}
>
<sphereGeometry />
<meshStandardMaterial color="red" />
<axesHelper scale={5} />
</mesh>
</mesh>
</>
)
}
export default Element3D
import { OrbitControls } from "@react-three/drei";
OrbitControls는 사용자가 마우스로 씬을 회전시키거나 확대/축소시킬 수 있다. 3d를 조작하기 위해 필요한 훅이다.
import { useFrame } from "@react-three/fiber";
useFrame은 애니메이션 루프 내에서 컴포넌트를 업데이트하는 데 사용된다.
import { useRef } from "react"
useRef는 DOM 요소나 컴포넌트의 참조를 저장하는데 사용되는 리액트 훅이다.
import { Mesh } from "three"
Mesh는 3D 객체 자체를 나타낸다. geometry(기하학)이나 material(재질)로 구성되는데, 그냥 3D 도형의 모양과 질감으로 생각하면 편할 것 같다.
const refMesh = useRef<Mesh | null>(null);
하단의 코드에 있는 Mesh 객체의 참조를 저장할 변수 생성
useFrame((state, delta) => {
if(refMesh.current != null) {
refMesh.current.rotation.z += delta
}
})
useFrame 훅을 사용해 매 프레임마다 실행되는 함수를 정의하며, 이 함수는 refMesh가 참조하는 z축 회전을 delta만큼 증가시킨다. z축 방향으로 매 시간마다 돌린다고 보면 된다.
<directionalLight position={[1, 1, 1]} />
x, y, z 순서로 [1, 1, 1] 위치에 방향성 광원을 생성한다. 특정 방향으로 빛을 쏘기 때문에 태양광과 비슷하다.
<axesHelper scale={10} />
axeHelper는 3D 공간의 축을 나타내는 헬퍼를 추가하고 크기를 10배로 확대한다.
헬퍼는 도형에 축을 나타내는 선을 말한다.
<mesh ref={refMesh} position-y={2} rotation-z={THREE.MathUtils.degToRad(45)} scale={[2, 1, 1]}>
</mesh>
mesh 객체를 생성하고 refMesh 참조에 연결한다. position-y는 y축 이동으로 객체를 2만큼 이동시킨다. rotation-z는 z축으로 회전시키며, 45도를 회전시킨다. scale은 객체의 크기를 나타내며, [2, 1, 1]로 x축은 2배 y축과 z축은 원래 1배 크기로 설정되었다.
<boxGeometry />
boxGeometry는 mesh의 형태 즉, 도형을 박스 형태로 설정한다. 이 코드를 사용하면 도형이 정육면체 모양으로 설정된다.
<meshStandardMaterial color="#e67e22" opacity={0.5} transparent={true} />
meshStandardMaterial은 mesh에 적용할 재질을 설정한다. 현재 코드는 재질이 설정되있지 않아 표준 재질을 사용하며, 색상은 주황색, opacity는 불투명도를 의미하는데 0이면 투명 1이면 불투명이다.이 코드에선 0.5여서 살짝 투명하고 transparent 속성을 true값으로 설정해 투명효과를 적용한다.
<axesHelper />
위에 작성한 것처럼 객체에 대한 좌표를 명확하게 하기위한 헬퍼를 생성하는데 현재 코드에선 생성된 도형에 헬퍼를 생성한다.
<mesh scale={[0.1, 0.1, 0.1]} position-y={2}>
<sphereGeometry />
<meshStandardMaterial color="red" />
<axesHelper scale={5} />
</mesh>
비슷한 코드라 한번에 묶어놨고 각 x, y, z의 크기가 0.1배이고 y축으로 2 이동한 객체를 생성하는데, sphereGeometry는 객체를 구 형태로 설정한다.
meshStandardMeterial로 구의 색상을 빨간색으로 설정하고 5배 크기인 헬퍼를 설정해준다.
이 코드를 실행하면
설정된 좌표에 y축으로 2 이동한 박스형태의 객체와 y축으로 2 이동한 구 형태의 객체가 z축으로 45도를 회전하는데 위의 useFrame에 따라 매 시간마다 계속 회전해서 무한히 회전한다.
강의 듣고 하나씩 따라해보는데 벌써 재밌다. 물론 아직 코드 이해가 잘 안되서 꾸준히 봐야겠지만 나만무 때 사용해서 쓸 수 있으면 좋을 것 같긴 하다. 킹갓주희님 찬양해
학습 시간 : 10 ~ 27시
'크래프톤 정글 > TIL' 카테고리의 다른 글
크래프톤 정글 week13, day101 - 나만의무기 팀 발표 및 기획 (0) | 2024.04.18 |
---|---|
크래프톤 정글 week13, day100 - 게시판 프로젝트 마무리 (0) | 2024.04.17 |
크래프톤 정글 week13, day98 - 잔디심기, 작성페이지 이미지 첨부 수정, jest (0) | 2024.04.15 |
크래프톤 정글 week13, day97 - 잔디심기, threeJs 에러수정, 이력서 작성 (0) | 2024.04.14 |
크래프톤 정글 week13, day96 - 잔디심기, 글 작성 페이지 UI 구현 (2) | 2024.04.12 |