반응형
Cannon.js
Cannon.js는 물리 엔진(Physics Engine)으로, Three.js에서 물리적인 충돌, 중력, 힘, 마찰 등을 구현할 때 사용됩니다.
Three.js 자체에는 물리 엔진이 없기 때문에, Cannon.js 같은 물리 엔진을 사용하여 사실적인 충돌 및 중력 효과를 추가할 수 있습니다.
Three.js + Cannon.js 연결 방법 (기본 예제)
이제 Three.js와 Cannon.js를 함께 사용하여 물리적으로 떨어지는 박스 만들기 예제를 살펴보겠습니다.
1. 필요한 라이브러리 불러오기
먼저, Cannon.js와 Three.js를 불러옵니다.
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js';
import * as CANNON from 'https://cdn.jsdelivr.net/npm/cannon-es@latest/dist/cannon-es.js';
2. Three.js & Cannon.js 기본 설정
// Three.js 설정
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Cannon.js 물리 세계 생성
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0); // 지구 중력 설정 (-Y 방향)
3. 바닥(ground) 만들기
// Three.js 바닥 생성
const groundGeometry = new THREE.PlaneGeometry(10, 10);
const groundMaterial = new THREE.MeshBasicMaterial({ color: 0xaaaaaa, side: THREE.DoubleSide });
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2; // X축으로 90도 회전
scene.add(ground);
// Cannon.js 바닥 생성
const groundBody = new CANNON.Body({
mass: 0, // 0 = 고정된 객체 (움직이지 않음)
shape: new CANNON.Plane()
});
groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0); // 바닥 회전
world.addBody(groundBody);
4. 떨어지는 박스 만들기
// Three.js 박스 생성
const boxGeometry = new THREE.BoxGeometry(1, 1, 1);
const boxMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const box = new THREE.Mesh(boxGeometry, boxMaterial);
scene.add(box);
// Cannon.js 박스 생성
const boxBody = new CANNON.Body({
mass: 1, // 질량 (0이 아니므로 중력의 영향을 받음)
shape: new CANNON.Box(new CANNON.Vec3(0.5, 0.5, 0.5)), // 크기 (1x1x1)
position: new CANNON.Vec3(0, 5, 0) // 초기 위치 (공중에 띄움)
});
world.addBody(boxBody);
5. 애니메이션 루프 & 물리 연동
const clock = new THREE.Clock(); // 시간 측정을 위한 Three.Clock()
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta(); // 프레임 간 시간 차이
world.step(1 / 60, delta, 3); // 물리 엔진 업데이트 (고정된 시간 스텝)
// Cannon.js의 위치 값을 Three.js 오브젝트에 반영
box.position.copy(boxBody.position);
box.quaternion.copy(boxBody.quaternion);
renderer.render(scene, camera);
}
animate();
결과
박스가 공중에서 시작 → 중력에 의해 바닥으로 떨어짐
Cannon.js의 물리 세계를 Three.js의 객체와 연동하여 렌더링
정리
Three.js | Cannon.js | |
---|---|---|
렌더링 | 3D 그래픽 | 물리 연산 |
오브젝트 위치 | object.position.set(x, y, z) | body.position.set(x, y, z) |
회전 값 | object.rotation 또는 quaternion | body.quaternion |
중력 적용 | ❌ 없음 | ✅ world.gravity.set(0, -9.82, 0) |
충돌 감지 | ❌ 직접 구현 필요 | ✅ 자동 처리 |
다음 단계
Cannon.js의 충돌 감지, 힘 적용, 마찰, 반발력 기능을 활용해 아래와 같은 것을 구현할 수 있어요.
✔ 공 튕기기 🏀
✔ 차량 물리 🚗
✔ 충돌 애니메이션 💥
https://schteppe.github.io/cannon.js/
반응형
'프론트엔드 > Three.js' 카테고리의 다른 글
atan2 (1) | 2025.02.02 |
---|---|
Raycaster (0) | 2025.02.01 |
Three.Clock (0) | 2025.02.01 |
오일러(Euler) vs. 쿼터니언(Quaternion) (1) | 2025.02.01 |
THREE.Euler (0) | 2025.02.01 |