Navigate
Search topics across all sections
Wireframe & Helpers
3D scenes are opaque by default — you see the final rendered pixels but nothing about the underlying structure. Helpers are your X-ray vision: wireframes reveal edges, axes show directions, grids show the ground plane, and box helpers outline bounding volumes.
You've placed a mesh at position [0, 0, 0] but it's not visible. Is it behind the camera? Inside another object? Too small? Too large? Without any visual reference points, you're debugging blind. You spend 20 minutes tweaking numbers before realizing the object was at the wrong scale.
Object not visible. No errors in console. Scene appears empty.
Real-world
Think of helpers as X-ray glasses for your 3D scene.
Without them, you see a finished painting. With them, you see the pencil sketch underneath. Wireframe shows you the skeleton — every triangle that makes up a surface. AxesHelper is like a compass, showing which way is X (red), Y (green), and Z (blue). GridHelper is graph paper on the floor, giving you spatial reference.
And BoxHelper draws a yellow outline around objects, like a spotlight operator marking where an actor should stand. Together, they transform a mysterious black box into a transparent workspace.
Wireframe
See the triangle mesh
AxesHelper
See the XYZ directions
GridHelper
See the ground plane
BoxHelper
See bounding boxes
Hands-On: Adding X-Ray Vision
Let's add helpers one by one to see how each reveals a different layer of your scene structure.
Step 1: Wireframe mode
// Wireframe shows every triangle edge
<mesh>
<torusKnotGeometry args={[1, 0.3, 100, 16]} />
<meshStandardMaterial
color="royalblue"
wireframe={true} // flip this on/off!
/>
</mesh>Setting wireframe to true on any material reveals the underlying triangle mesh. You can see exactly how the geometry is constructed — more triangles means smoother curves but higher GPU cost.
Step 2: AxesHelper and GridHelper
// Red = X, Green = Y, Blue = Z
<axesHelper args={[3]} />
// Grid on the XZ plane (the floor)
<gridHelper
args={[10, 10, "#666", "#444"]}
position={[0, -1, 0]}
/>AxesHelper draws three colored lines from the origin. Remember: RGB maps to XYZ. The GridHelper draws a grid on the floor plane, giving you spatial reference for where objects are positioned.
Step 3: BoxHelper for bounding volumes
const meshRef = useRef<THREE.Mesh>(null);
const boxRef = useRef<THREE.BoxHelper>(null);
// Update every frame to track movement
useFrame(() => {
boxRef.current?.update();
});
<mesh ref={meshRef}>
<torusKnotGeometry args={[1, 0.3, 100, 16]} />
<meshStandardMaterial color="royalblue" />
</mesh>
{meshRef.current && (
<boxHelper
ref={boxRef}
args={[meshRef.current, "#facc15"]}
/>
)}BoxHelper draws a wireframe box around any object, showing its axis-aligned bounding box (AABB). This is useful for understanding the spatial extent of complex shapes and debugging collision areas.
What you just learned
Wireframe mode reveals the triangle mesh that makes up any geometry by setting wireframe={true} on the material.
AxesHelper draws XYZ axes (Red=X, Green=Y, Blue=Z) from the origin as a directional compass.
GridHelper creates a reference grid on the floor plane, sized to match your scene scale.
BoxHelper draws a bounding box around objects — call .update() every frame if the object moves.
Question
If you can toggle helpers on and off at runtime, what would be the ideal debugging workflow? Would you keep all helpers on by default, or add them one at a time as you need specific information?
Think about it...
You have a mesh that's rotating, and its BoxHelper stays frozen at the original position. What's missing?
Hint: BoxHelper calculates its bounds only once at creation time...
Try These Challenges
Put what you learned into practice. Try each challenge in the demo above using the Leva controls, then check the solution.
Try This!
Beginner
Toggle wireframe — see the edges!
Try This!
Beginner
Set axesSize to 5 — giant compass
Try This!
Beginner
Toggle BoxHelper — see the bounds
These are the patterns that trip up developers most often. Switch between Wrong and Fixed to compare the code side by side.
// Helpers everywhere, even in production
<Canvas>
<axesHelper args={[5]} />
<gridHelper args={[10, 10]} />
<boxHelper args={[mesh, "yellow"]} />
<MyScene />
</Canvas>// BoxHelper created once, never updated
<boxHelper args={[meshRef.current, "yellow"]} />
// The box stays in the original position
// even as the mesh moves and rotates// Default size might not fit your scene
<axesHelper />
// Size 1 is invisible in a large scene
// Size 100 overwhelms a small sceneBest Practices
Use Leva for Debug Toggles
Add Leva controls for wireframe, helpers, and stats. Toggle them on/off without touching code. Hide the Leva panel in production builds.
Remember RGB = XYZ
Red is X, Green is Y, Blue is Z. This convention is universal across all 3D tools and engines. Burn it into memory.
Scale Helpers to Your Scene
Helpers have a size parameter. Match it to your scene scale — a 2-unit axis in a 100-unit scene is invisible. Use the grid to calibrate.
Use GizmoHelper for Orientation
Drei's GizmoHelper puts a small orientation cube in the corner of your viewport. It shows which axis you're looking along without cluttering the main scene.