Skip to content

API Reference

EntrypointUse it for
threejs-debug-viewNative runtime: view definitions, render planning, TSL compositor, WebGPU helpers, and public types.
threejs-debug-view/r3fOptional R3F adapter: DebugViewLayer, DebugViews, bundled Leva shell, and useDebugViewsControls().

See R3F for what ships on npm versus the repo demo and docs site.

Import from threejs-debug-view when your app owns the WebGPU render loop. Full walkthrough: Native Runtime.

APIUse when
createDebugPipelineRuntime()Single compositor output (overlay, breakdown, grid, etc.)
createDebugViewportRenderer()Panes need different resolutionScale or per-pane cameras
requiresViewportRuntime()Choosing between the two paths after createDebugViewportPlan()

createDebugViewportRenderer() options:

OptionDefaultNotes
overlayOpacity1Per-pane opacity. Viewport cells are opaque single-view passes, not compositor overlay blends.
dividerStyleForwarded to uniforms only; TSL dividers are not drawn between scissor panes.

Pane rects are cached when the viewport renderer is constructed. Rebuild when the plan changes.

  • resolveDebugViewLayout() — normalize layout presets into rows, columns, and slots
  • createDebugRenderPlan() — pass and pipeline view selection for a layout
  • createDebugPipelineRuntimeKey() — stable rebuild key for runtime caches
  • createDebugViewportPlan() / createDebugViewportRenderGraphPlan() — multi-pane viewport graphs
  • createDebugViewUniforms() / updateDebugViewUniforms() — TSL uniform state
  • createDebugViewportLabels() / createDebugViewportRects() — viewport presentation helpers
  • readHeatmapCostFromCanvas() — shader-cost pixel sampling

The root export includes layout/pane helpers and the DebugViewsOptions type for custom native UI:

  • DebugViewsOptions, DebugViewsControlValues
  • createPaneAssignmentsKey(), createViewportViews(), getVisiblePaneCount(), getVisiblePaneCountForLayout()
  • isPaneAssignmentLayout(), usesPaneAssignments()

Import from threejs-debug-view/r3f.

Optional R3F adapter layer with default views and Leva controls.

<DebugViewLayer />

Use DebugViews when your app owns controls, layout state, custom views, or viewport assignments.

DebugViewLayer mounts Leva on document.body by default. Set showLeva={false} when mounting DebugViewLeva elsewhere.

PropPurpose
viewsOptional custom view list. Defaults to DEFAULT_DEBUG_VIEWS.
viewLabelsOptional labels passed to the bundled Leva controls.
maxPaneCountUpper bound for panes, rows, and columns in the controls.
showEnabledControlShows the Leva Enabled toggle. Defaults to true. The demo sets this to false.
showLevaMounts the bundled Leva panel on document.body. Defaults to true.
showLabelsOverrides the Leva viewport-label toggle.
showLegendsOverrides the Leva diagnostic-legend toggle.
layoutOverrides the Leva layout preset (for example breakdown).
diagonalAngleOverrides the Leva diagonal angle for split-diagonal and breakdown.
viewportViewsOverrides Leva pane assignments with fixed DebugViewportView entries.

Bundled Leva panel for debug view controls. Mount it yourself when the panel should live in a specific place in your app shell while sharing the same Leva store as useDebugViewsControls.

R3F component for presenting debug views inside a <Canvas>.

PropPurpose
viewsRegistered debug views.
activeViewSelected view index for single/overlay flows.
layoutLayout preset or layout config.
paneCountNumber of visible panes for row, column, and grid layouts.
diagonalAngleAngle in degrees for split-diagonal and breakdown. breakdown defaults to 25 degrees.
maxDiagonalAngleOptional override for the default 45 degree diagonal angle clamp.
viewportViewsExplicit pane assignments for fixed views, labels, cameras, or resolution scale.
showLabelsRenders DOM labels over panes (for example Shader Complexity, Normal).
showLegendsShows bottom diagnostic ramps (shader cost, overlap). Defaults to true.
viewportLabelsLabel overrides or formatter.
overlayOpacityBlend amount for overlay mode.
lineWidthDivider hairline thickness in normalized screen space (default thin).
edgeColorSilver rim at divider edges as RGB [0–1, 0–1, 0–1].
coreColorCenter fill inside dividers as RGB [0–1, 0–1, 0–1].

layout decides the arrangement, paneCount decides how many panes are visible, and viewportViews decides what each explicit pane renders. Simple pane assignments use the compositor path; per-pane cameras and resolutionScale use the viewport/scissor path.

Returns Leva-backed control state to spread onto DebugViews. See Quick Start — bring your own controls.

Also exported from /r3f: mountDebugViewLeva, DEBUG_VIEW_LEVA_THEME.

interface DebugView {
id?: string
label: string
node?: DebugNode
mode?: "passthrough" | "normal" | "depth" | "heatmap"
source?: DebugViewSource
scale?: number
bias?: number
}
interface DebugViewportView {
view: number | DebugViewSource | DebugView
label?: string
camera?: Camera
resolutionScale?: number
}

resolutionScale is normalized to 1, 0.5, or 0.25.

Built-in DebugViewSource values:

SourceNotes
beautyFinal scene color.
normalView-space geometry normals.
depthView-space depth visualization.
albedo / baseColorBase color without lighting.
materialNormal / normalMapMaterial-perturbed normals.
emissiveMaterial emissive contribution.
roughnessPacked material scalar, defaults to 1 when unsupported.
aoPacked material AO, defaults to 1 when unsupported.
metallic / metalnessPacked material scalar, defaults to 0 when unsupported.
opacity / transparencyPacked alpha scalar.
wireframeOverride-material pass.
lightingOnlyNeutral lighting override pass.
reflectionOnlyReflective override pass.
overdrawMeasured overlap heatmap (contributor layer count). Click the viewport to sample integer layers from the pass buffer.
overdrawVisualAdditive overlap visualization (approx).
lightComplexityLight overlap heatmap (v1 analytic point/spot/rect counter; globals excluded).
shaderCostShader-complexity heatmap from shader-unit buckets. Click the viewport in DebugViewLayer to sample a pixel; the legend shows shader complexity when idle.

shaderCost is not a native GPU instruction counter. Render-pass timing and overlap diagnostics are separate signals, not ALU/TEX/occupancy data.

Use createCustomDebugView() when a custom TSL node may be recreated by React but should keep a stable logical identity:

const fresnel = createCustomDebugView({
id: "shader:fresnel",
label: "Fresnel",
node: fresnelNode,
mode: "passthrough",
})

The compositor runtime rebuilds when a custom node instance changes. The viewport render graph uses id in stable pass keys.

  • DEFAULT_DEBUG_VIEWS, getDebugViewLabels()
  • createCustomDebugView()
  • createDebugRenderPlan()
  • createDebugPipelineRuntime()
  • createDebugViewportRenderer()
  • createDebugViewportPlan()
  • createDebugViewportRenderGraphPlan()
  • requiresViewportRuntime()