Navigate

Search topics across all sections

GitHub
Debug & Helpers

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.

terminal
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

App.tsxTSX
// 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

App.tsxTSX
// 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

App.tsxTSX
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.

1
Leaving helpers in production builds
Your users see grid lines and axis arrows on top of your beautiful scene
Don't do this
App.tsxTSX
// Helpers everywhere, even in production
<Canvas>
  <axesHelper args={[5]} />
  <gridHelper args={[10, 10]} />
  <boxHelper args={[mesh, "yellow"]} />
  <MyScene />
</Canvas>
Helpers are debugging tools, not production features. Wrap them in environment checks or use a debug toggle so they never ship to users. Leva panels should also be hidden in production.
2
BoxHelper not updating when the mesh transforms
The bounding box stays frozen at the original position
Don't do this
App.tsxTSX
// BoxHelper created once, never updated
<boxHelper args={[meshRef.current, "yellow"]} />
// The box stays in the original position
// even as the mesh moves and rotates
BoxHelper computes the bounding box once on creation. If the mesh moves, rotates, or scales, you need to call .update() every frame to keep the helper in sync.
3
AxesHelper too small or too large for the scene
Axis lines are either invisible or they stretch to infinity
Don't do this
App.tsxTSX
// Default size might not fit your scene
<axesHelper />
// Size 1 is invisible in a large scene
// Size 100 overwhelms a small scene
AxesHelper draws lines from the origin. The default size is 1, which is often too small to see. Scale the helper to match your scene dimensions, or better yet, make it adjustable with a GUI control.

Best 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.