Skip to content

Viewport Labels

Label geometry comes from the native createDebugViewportLabels() helper. The optional R3F adapter renders those labels in DOM space when you set showLabels on DebugViews.

import {
DEFAULT_DEBUG_VIEWS,
createDebugViewportLabels,
createDebugViewportPlan,
resolveDebugViewLayout,
} from "threejs-debug-view"
const layout = resolveDebugViewLayout("row")
const viewportPlan = createDebugViewportPlan({
views: DEFAULT_DEBUG_VIEWS,
layout,
paneCount: 4,
})
const labels = createDebugViewportLabels(
viewportPlan.pipelineViews,
layout,
["Beauty", "Normals", "Depth", "Albedo"],
)

Use the returned rects and strings in your own UI layer.

Enable labels with showLabels.

<DebugViews
views={views}
layout="row"
paneCount={4}
showLabels
viewportLabels={["Beauty", "Normals", "Depth", "Albedo"]}
/>

With explicit pane assignments, labels follow the viewportViews plan:

<DebugViews
views={views}
viewportViews={[
{ view: "beauty", label: "Reference" },
{ view: "normal", label: "Geometry normals" },
]}
layout={{ mode: "row", paneCount: 2 }}
showLabels
/>

You can also pass a formatter function when labels need to be generated from the view and viewport index.

For split-diagonal and breakdown, labels are positioned in DOM space over the canvas (not in world space). Band geometry matches the TSL compositor: projected coordinates use WebGPU screenUV, where y = 0 is the top of the viewport.

Each tag is centered inside its band at a top scanline so it lines up with the slanted dividers you see in the render. Use viewportViews when pane order or short labels differ from the default view list:

<DebugViews
views={views}
layout="breakdown"
diagonalAngle={13}
viewportViews={[
{ view: "normal" },
{ view: "shaderCost", label: "Complexity" },
{ view: "albedo", label: "Albedo" },
{ view: "depth" },
]}
showLabels
showLegends
/>

See Presentation Routing for the breakdown screenshot and the repo ?capture=social preset.