@react-three/rapier (Physics Engine)@react-three/rapier is a powerful and performant physics engine integration for React Three Fiber. It allows you to add realistic physics simulations to your 3D scenes, enabling objects to collide, react to forces, and interact with each other in a physically accurate way. It leverages the Rapier physics engine, which is written in Rust and compiled to WebAssembly for high performance.
To integrate @react-three/rapier into your React Three Fiber project, you'll need to install the necessary packages:
npm install @react-three/fiber @react-three/drei @react-three/rapier rapier-js
# or
yarn add @react-three/fiber @react-three/drei @react-three/rapier rapier-js
@react-three/fiber: The core React Three Fiber library.@react-three/drei: Provides useful helpers and abstractions (like OrbitControls).@react-three/rapier: The React Three Fiber bindings for Rapier.rapier-js: The core Rapier physics engine.<Physics>: This component acts as the physics world container. All physics-enabled objects must be children of this component. You can enable debug visuals by adding the debug prop.<RigidBody>: This component wraps your 3D meshes and makes them participate in the physics simulation. You can define their type (e.g., dynamic, fixed, kinematic) and collider shape (e.g., cuboid, ball).colliders prop: Used on <RigidBody> to define the shape of the physics collider. Common values include "cuboid", "ball", "trimesh", etc.useFrame hook: While Rapier handles the physics simulation, you might still use useFrame to apply forces, read positions, or implement custom logic that interacts with the physics world.This example demonstrates a basic setup with a ground plane and several falling boxes, all interacting with the Rapier physics engine. Note that this requires a React environment to run.
import React, { useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { OrbitControls, Plane } from '@react-three/drei';
import { Physics, RigidBody, Debug } from '@react-three/rapier';
function Box(props) {
const ref = useRef();
return (
<RigidBody ref={ref} colliders="cuboid" {...props}>
<mesh>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="orange" />
</mesh>
</RigidBody>
);
}
export default function App() {
return (
<Canvas camera={{ position: [0, 5, 10], fov: 50 }}>
<ambientLight intensity={0.5} />
<directionalLight position={[10, 10, 5]} intensity={1} />
<OrbitControls />
<Physics debug> <!-- Add debug prop to visualize colliders -->
{/* Ground Plane */}
<RigidBody type="fixed" colliders="cuboid">
<Plane args={[20, 20]} rotation-x={-Math.PI / 2} position-y={-0.5}>
<meshStandardMaterial color="lightgray" />
</Plane>
</RigidBody>
{/* Falling Boxes */}
<Box position={[0, 5, 0]} />
<Box position={[0.5, 7, 0.5]} />
<Box position={[-0.5, 9, -0.5]} />
</Physics>
</Canvas>
);
}