-
three.js 입문 (ing)FrontEnd/HTML, CSS 2023. 9. 30. 13:32
- Three.js 는 크게 Scene, Camera, Render 로 나뉨
- Scene : 렌더링 할 모든 객체와 광원을 저장하는 공간. (Scene이 없다면 어떠한 객체도 표시 못함)
- Camera: Scene 객체를 어떻게 촬영하여 보여줄 것인지 결정
- Render: Scene과 Camera 객체를 넘겨 받아 렌더링 한다.
- three.js 불러오기
- Option1 :install with NPM and a build tool
npm init # three.js npm install --save three # vite npm install --save-dev vite npx vite
- Option2: import from a CDN
<script type="importmap"> { "imports": { "three": "https://unpkg.com/three@<version>/build/three.module.js", "three/addons/": "https://unpkg.com/three@<version>/examples/jsm/" } } </script> <script type="module"> import * as THREE from 'three'; </script>
2. Scene 생성
- 렌더링 할 모든 객체와 광원을 저장하는 공간.
let scene = new THREE.Scene(); // scene.background = new THREE.Color("skyblue"); //Scene의 배경색을 설정 const mesh = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1, 5, 5, 5), new THREE.MeshBasicMaterial({ color: 0xff0000 }) ); //const geometry = new THREE.BoxGeometry(1, 1, 1); //const material = new THREE.MeshBasicMaterial({ color: 'rgb(255, 0, 0)' }); //const mesh = new THREE.Mesh(geometry, material); scene.add(mesh); //씬에는 메쉬라는 것과 카메라를 담아줘야 함. //메쉬는 geometry, material 의 조합인데 geometry는 몸체(화면에 보여줄). material은 꼬리(몸체 속성) 처럼 생각하면 됨.
3. Camera 생성
- Scene 객체를 어떻게 촬영하여 보여줄 것인지 결정
- 아래는 카메라 종류
-
- PerspectiveCamera:
- 3D 장면을 렌더링하기 위한 일반적인 카메라입니다.
- 원근법을 사용하여 멀리 있는 객체가 작게 보이고 가까이 있는 객체가 크게 보이는 시각적 효과를 제공합니다.
- OrthographicCamera:
- 원근법이 적용되지 않는 평면적인 뷰를 만들기 위한 카메라입니다. (1인칭 게임에 사용 .RTS 게임)
- 멀리 있는 객체와 가까이 있는 객체가 동일한 크기로 렌더링됩니다.
- CubeCamera:
- 주로 큐브맵(cubemap) 렌더링에 사용되는 카메라입니다.
- 한 번에 여러 방향에서 뷰를 렌더링하여 큐브맵 텍스처를 생성합니다.
- ArrayCamera:
- 여러 카메라를 배열로 그룹화하여 사용할 수 있는 카메라입니다.
- 한 번에 여러 시점에서 렌더링을 수행할 수 있습니다.
- StereoCamera:
- 스테레오 3D 렌더링을 지원하는 카메라입니다.
- 두 개의 하위 카메라를 사용하여 왼쪽 및 오른쪽 눈을 동시에 렌더링합니다.
- VRPerspectiveCamera 및 VROrthographicCamera:
- 가상 현실(VR) 애플리케이션을 위한 카메라입니다.
- VR 환경에서 3D 장면을 렌더링하고 사용자의 시점과 상호 작용을 지원합니다.
- PerspectiveCamera:
const camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height); scene.add(camera) //카메라 생성 후 이것도 씬에 꼭 넣어줘야 함. (안 넣어도 작동은 되지만 이후 버그 유발 가능) // constructor PerspectiveCamera(fov?: number | undefined, aspect?: number | undefined, near?: number | undefined, far?: number | undefined): THREE.PerspectiveCamera // @remarks — Together these define the camera's viewing frustum. // @param fov — Camera frustum vertical field of view. Default 50. // @param aspect — Camera frustum aspect ratio. Default 1. // aspect 는 보통 (canvas의 폭/canvas 높이) // @param near — Camera frustum near plane. Default 0.1. // @param far — Camera frustum far plane. Default 2000.
4. Renderer생성 -
- 만들어진 Scene과 Camera를 받아와서 화면에 render 해줌
- renderer를 통해 캔버스의 크기 조정 가능
- Three.js의 renderer.setSize()를 사용하면 Three.js 렌더러가 크기를 자동으로 조정하고 렌더링에 대응할 수 있지만, HTML 내에서 캔버스의 크기를 직접 설정하면 Three.js 렌더러는 캔버스 크기 변경을 감지하지 못하고 문제가 발생할 수 있음. 일반적으로 Three.js를 사용할 때는 renderer.setSize()를 사용하여 캔버스 크기를 조정하는 것이 좋음
const canvas = document.querySelector('canvas.webgl'); const renderer = new THREE.WebGLRenderer({ canvas:canvas }); renderer.setSize(800, 600); //렌더러가 canvas 크기 조정 renderer.render(scene, camera); //씬과 카메라를 받아와 렌더링 해줌
- 위와 같이 쭉 이어 왔다면 에러는 발생하지 않겠지만 만들어둔 mesh는 보여지지 않을 것임. 카메라의 위치와 메쉬의 위치를 정하지 않았기 때문.
mesh.position.x = 1 mesh.position.y = 1 mesh.position.z = 1 // mesh.position.set(1,1,1) camera.position.x = 1 camera.position.y = 1 camera.position.y = 1 // camera.postion.set(1,1,1) //mesh의 position을 변경하면 우리가 x,y,z축에 따라 이동을 하지만 //카메라의 위치를 변경할 경우에는 카메라가 x,y,z축에 따라 이동을 하는 것이므로 우리 눈에 보여지는 mesh는 카메라에 준 값과 반대 돼서 보임
5. rotation과 scale을 통해 모형 변경 가능
6. window.requestAnimationFrame() 을 이용해서 재귀 로직을 짜면 애니메이션 효과 주기 가능 .
7. THREE.Group() 을 통해 그룹을 만들면 여러 매쉬를 하나의 묶음으로 만들어서 조작 가능
const group = new THREE.Group(); //group 생성 group.scale.y = 2; group.rotation.y = 0.2; scene.add(group); // 그룹 생성 후 씬에 담아주기 const cube1 = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial({ color: 0xff0000 }) ); cube1.position.x = -1.5; group.add(cube1); // 매시를 만들어서 원하는 그룹에 넣기 const cube2 = new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial({ color: 0x00ff00 }) ); cube2.position.x = 0; group.add(cube2); // 매시를 만들어서 원하는 그룹에 넣기 const clock = new THREE.Clock(); //THREE.Clock const tick = () => { const elapsedTime = clock.getElapsedTime(); // 경과시간 group.rotation.y = Math.PI * elapsedTime; //속성을 변경하면 그 그룹 전체에 적용됨 (group.children[idx] 로도 개별 접근 가능) group.position.x = Math.cos(elapsedTime); //삼각함수를 이용하면 범위 내 좌표 이동도 가능 group.position.y = Math.sin(elapsedTime); camera.lookAt(group.position); // Vector 값을 이용한 카메라 위치 조정 window.requestAnimationFrame(tick); //재귀 renderer.render(scene, camera); };
'FrontEnd > HTML, CSS' 카테고리의 다른 글
three.js 공부하기 전 용어 정리 (0) 2023.09.29 [html,css] canvas animation (ing) (0) 2023.09.27 canvas 정리 (0) 2023.09.27 [css] linear-gradient (0) 2023.09.27 [css] min(),max(),clamp() : css 함수를 통한 반응형 웹 (0) 2023.09.26