Debugging 3D applications can be challenging due to their visual nature and complex interactions. Tools like Leva and @react-three/drei's Stats component provide powerful ways to inspect, modify, and monitor your React Three Fiber scenes in real-time.
Leva is a powerful, declarative GUI component that facilitates real-time tweaking of parameters within your R3F applications. It allows you to create interactive controls (like sliders, color pickers, and checkboxes) that directly manipulate values in your 3D scene, making it easier to fine-tune visuals and behaviors without constantly editing code.
npm install leva
# or
yarn add leva
useControls Hook: To add controls, import and use the useControls hook from leva within your React component. This hook returns an object containing the current values of your controls.import { useControls } from 'leva';
function MyDebuggedBox() {
const { color, positionX } = useControls({
color: '#ff0000', // Initial color
positionX: { value: 0, min: -5, max: 5, step: 0.1 }, // Slider for X position
});
return (
<mesh position={[positionX, 0, 0]}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={color} />
</mesh>
);
}
You can also add the <Leva /> component to your root component to configure the appearance of the GUI (e.g., <Leva collapsed />).
The @react-three/drei library provides a convenient Stats component to monitor your scene's performance, including frames per second (FPS), memory usage, and more.
npm install @react-three/drei
# or
yarn add @react-three/drei
Stats and add it inside your <Canvas> component.import { Canvas } from '@react-three/fiber';
import { Stats } from '@react-three/drei';
function MySceneWithStats() {
return (
<Canvas>
<Stats /> <!-- This will display FPS and other stats -->
<!-- Your 3D scene components -->
</Canvas>
);
}
This conceptual example shows how you might integrate both Leva controls and performance stats into your R3F application. Note that this requires a React environment to run.
import React from 'react';
import { Canvas } from '@react-three/fiber';
import { Stats } from '@react-three/drei';
import { useControls, Leva } from 'leva';
function DebuggableBox() {
const { color, scale, rotationSpeed } = useControls({
color: '#00ff00',
scale: { value: 1, min: 0.1, max: 2, step: 0.1 },
rotationSpeed: { value: 0.01, min: 0, max: 0.1, step: 0.001 },
});
const meshRef = useRef();
useFrame(() => {
if (meshRef.current) {
meshRef.current.rotation.x += rotationSpeed;
meshRef.current.rotation.y += rotationSpeed;
}
});
return (
<mesh ref={meshRef} scale={scale}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={color} />
</mesh>
);
}
export default function App() {
return (
<>
<Leva collapsed /> <!-- Leva GUI -->
<Canvas>
<Stats /> <!-- Performance Stats -->
<ambientLight />
<pointLight position={[10, 10, 10]} />
<DebuggableBox />
</Canvas>
</>
);
}