Native Runtime
The root export threejs-debug-view is the canonical native runtime. The optional /r3f adapter is a thin layer on top of the same pipeline.
Use the native path when you:
- own the WebGPU render loop and UI
- want full control over layout, overlays, and viewport presentation
- do not need React, R3F, or Leva
For install commands, see Quick Start — Native. For the optional adapter, see R3F.
Single-view compositor loop
Section titled “Single-view compositor loop”import { DEFAULT_DEBUG_VIEWS, createDebugRenderPlan, createDebugPipelineRuntime, createDebugViewUniforms, resolveDebugViewLayout, updateDebugViewUniforms,} from "threejs-debug-view"import { WebGPURenderer } from "three/webgpu"
const views = DEFAULT_DEBUG_VIEWSconst activeView = 0const layout = resolveDebugViewLayout("single")const plan = createDebugRenderPlan(views, activeView, layout)const uniforms = createDebugViewUniforms()
const runtime = createDebugPipelineRuntime( scene, camera, plan, layout, renderer as WebGPURenderer, uniforms,)
function animate() { updateDebugViewUniforms( uniforms, plan.activePipelineView, layout, plan.pipelineViews.length, 1, ) runtime.pipeline.render() requestAnimationFrame(animate)}Use createDebugPipelineRuntime for overlay, breakdown, grid, and other layouts where the TSL compositor blends multiple views in one fullscreen pass.
Multi-pane viewport rendering
Section titled “Multi-pane viewport rendering”When a pane uses a custom camera or resolutionScale below 1, use the viewport planner and viewport renderer:
import { DEFAULT_DEBUG_VIEWS, createDebugViewportPlan, createDebugViewportRenderGraphPlan, createDebugViewportRenderer, createDebugViewUniforms, requiresViewportRuntime,} from "threejs-debug-view"
const viewportPlan = createDebugViewportPlan({ views: DEFAULT_DEBUG_VIEWS, viewportViews: [ { view: "beauty" }, { view: "normal", resolutionScale: 0.5 }, ], layout: "split-h",})
if (requiresViewportRuntime(viewportPlan)) { const viewportGraph = createDebugViewportRenderGraphPlan(viewportPlan) const uniforms = createDebugViewUniforms()
const viewportRenderer = createDebugViewportRenderer({ gl: renderer, scene, defaultCamera: camera, viewportPlan, viewportGraph, uniforms, })
// Each frame: viewportRenderer.render()}createDebugViewportRenderer clears the canvas, renders each pane into a scissor rect, adjusts per-pane camera aspect when needed, and restores the renderer’s previous viewport/scissor state.
Compositor vs viewport path
Section titled “Compositor vs viewport path”Compositor (createDebugPipelineRuntime) | Viewport (createDebugViewportRenderer) |
|---|---|
| One shader graph blends multiple views | One pass per pane, routed with GL scissor/viewport |
overlayOpacity blends overlay layouts | overlayOpacity defaults to 1 (opaque panes) |
| TSL divider lines between cells | No divider lines — panes are separated physically |
| Layout uniforms updated each frame | Pane rects computed once when the renderer is created |
Recreate the viewport renderer when viewportPlan or viewportGraph changes. Optional overlayOpacity and dividerStyle are forwarded to updateDebugViewUniforms; single-view passes do not draw compositor dividers or overlay blends.
Call requiresViewportRuntime(viewportPlan) after planning to choose between the compositor and viewport paths.
Planning helpers
Section titled “Planning helpers”These native exports are framework-agnostic — safe in tests, tools, or custom engines:
| Helper | Purpose |
|---|---|
resolveDebugViewLayout | Normalize layout presets into rows, columns, and slots |
createDebugRenderPlan | Select passes and pipeline views for a layout |
createDebugViewportPlan | Map pane assignments to viewport cells |
createDebugViewportRenderGraphPlan | Group cells into render passes |
requiresViewportRuntime | true when any pane uses a custom camera or sub-full resolutionScale |
createDebugPipelineRuntimeKey | Stable cache key when rebuilding pipelines |
readHeatmapCostFromCanvas | Sample shader-cost heatmap pixels from a canvas |
R3F adapter
Section titled “R3F adapter”threejs-debug-view/r3f adds useFrame / useThree wiring, DOM overlays for labels and legends, and optional Leva controls. It calls the same native runtime documented here — it does not duplicate the WebGPU pipeline.
See API Reference for R3F prop detail.