- Udemy의 Three.js and TypeScript 강의를 듣고 정리한 내용을 기록한다.
- 11. Renderer 부터 13. Object3D 까지.
Renderer
- Scene과 Camera에 대한 정보를 canvas 요소 내부에 그려내는 역할을 수행한다.
- Three.js에서 가장 보편적으로 쓰이는 Renderer는 WebGLRenderer이다.
- WebGL을 사용하여 GPU 가속 이미지 처리를 진행하고, Renderer가 canvas에 2D 이미지를 생성할 수 있도록 한다.
⇒ 빠른 성능
- WebGL을 사용하여 GPU 가속 이미지 처리를 진행하고, Renderer가 canvas에 2D 이미지를 생성할 수 있도록 한다.
import * as THREE from 'three';
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
renderer.render(scene, camera);
- WebGLRenderer 생성자로 renderer를 생성함.
- 이 때 이미 존재하는 HTML 요소를 전달하지 않으면, renderer가 자체적으로 canvas 요소를 생성함.
- renderer가 생성한 canvas를 화면상에 노출시키기 위해 appendChild를 통해 HTML에 붙임.
- setSize를 통해 렌더러의 화면 크기를 윈도우 크기로 변경하고 있다.
- resize 이벤트를 통해 윈도우 크기가 변화할 때마다 renderer의 크기를 변경하고 있다.
- render 함수에 렌더링하려는 Scene과 카메라를 전달함으로써 캔버스에 3D 장면을 띄울 수 있다.
- WebGLRenderer 생성자에 따로 만든 canvas 요소를 전달함으로써, 그 캔버스에 renderer가 렌더링 하도록 만들 수 있다.
- 이를 활용해 윈도우 창 전체가 아닌, 웹페이지의 원하는 부분에만 Three.js 캔버스를 띄우는 방식으로 활용할 수 있다.
// 미리 만들어둔 캔버스 요소를 WebGLRenderer 생성자에 넘기는 예시
import * as THREE from 'three';
const canvas = document.getElementById('canvas') as HTMLCanvasElement;
const renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.setSize(400, 200);
Animation Loop
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
stats.update();
}
animate();
- requestAnimationFrame: Three.js의 메서드가 아니라, 브라우저에서 지원하는 메서드.
- 웹에서 애니메이션을 구현할 때 쓰이는 함수이다.
- 이 함수의 인자로 넘긴 콜백 함수를 디스플레이 주사율에 맞춰 실행한다.
ex) 60Hz: 1초에 60번 실행된다. / 120Hz: 1초에 120번 실행된다.
주사율이 120Hz일 때 | 주사율이 60Hz일 때 |
- 따라서 애니메이션에 사용되는 값에 그냥 숫자를 사용하는 것보다는, 모든 디스플레이 주사율에서 똑같은 모습을 보일 수 있도록 delta를 사용하는 것이 좋다. ⇒ Frame Independent animating
import * as THREE from 'three';
const clock = new THREE.Clock();
let delta;
function animate() {
requestAnimationFrame(animate);
delta = clock.getDelta();
cube.rotation.x += delta;
cube.rotation.y += delta;
renderer.render(scene, camera);
stats.update();
}
animate();
- Three.js의 Clock 생성자로 Clock 객체를 생성하고 requestAnimationFrame이 실행될 때마다 delta 값을 갱신하고 있다.
+) 참고
On Demand Rendering
- 매 프레임마다 렌더링을 새로 하는 것이 아닌, 필요할 때만 렌더링함으로써 성능을 개선시키는 것을 의미한다.
→ 예제 코드에서는 매 프레임마다 requestAnimationFrame 메서드를 통해 큐브를 회전시키는 애니메이션을 재생하고 있다.
→ 이를 OrbitControl로 큐브를 직접 회전시켰을 때만 재렌더링을 하게끔 코드를 변경한다.
import * as THREE from 'three';
/* 중략 */
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', function () {
// OrbitControl로 인한 변경이 일어났을 때만 재렌더링 하게끔 이벤트리스너를 추가한다
renderer.render(scene, camera);
});
/* 중략 */
function animate() {
requestAnimationFrame(animate);
stats.update();
}
animate();
renderer.render(scene, camera);
Object3D
: Three.js에서 다양한 객체들의 바탕이 되는 클래스.
- 앞서 살펴본 Camera나 Scene도 Object3D를 확장한 클래스이다.
- 이외에도 Mesh나 Light 등의 다양한 클래스가 존재한다.
아래는 Object3D의 몇 가지 자주 접하게 될 속성들을 나열해봤다.
이름 | 설명 |
position | 물체의 좌표값을 의미한다. |
rotation | 물체의 회전값을 의미한다. |
visible | 물체의 렌더링 여부를 의미한다. |
scale | 물체의 스케일(크기 값)을 의미한다. |
- 이 다음이 Object3D의 구조라 조금 더 보고 쓸까 했는데, 내용이 길어질 것 같아 분리하기로.
- 별개로 Delta에 관한 개념이 왜 익숙한걸까 했는데, Unity에서도 비슷한 것이 있었던 것 같다... 전에 배웠던 내용이나 해봤던 비슷한 개념이 등장하는게 꽤 즐겁다.
'공부 > etc' 카테고리의 다른 글
Three.js and TypeScript (5) (2) | 2024.11.18 |
---|---|
Electron + Vite + React 환경 세팅 살펴보기 (2) | 2024.11.15 |
Three.js and TypeScript (3) (0) | 2024.11.13 |
Three.js and TypeScript (2) (0) | 2024.11.12 |
Three.js and TypeScript (1) (1) | 2024.11.09 |