Custom Debug Views
Custom views register on the native root export. Pass the same view list into createDebugRenderPlan() or, with the optional R3F adapter, into DebugViews.
For simple shader debugging, add a DebugView object with a TSL node:
import { float, vec4 } from "three/tsl"
const constantView = { label: "Constant", node: float(0.5), mode: "depth" as const, scale: 1 }const colorView = { label: "Custom Color", node: vec4(1, 0, 0, 1), mode: "passthrough" as const }When React may recreate the node instance between renders, prefer createCustomDebugView() with a stable id.
Native
Section titled “Native”import { float, vec4 } from "three/tsl"import { createCustomDebugView, DEFAULT_DEBUG_VIEWS, createDebugRenderPlan, createDebugPipelineRuntime, createDebugViewUniforms, resolveDebugViewLayout,} from "threejs-debug-view"
const fresnelView = createCustomDebugView({ id: "shader:fresnel", label: "Fresnel", node: vec4(float(1), float(0), float(0), float(1)),})
const views = [...DEFAULT_DEBUG_VIEWS, fresnelView]const plan = createDebugRenderPlan(views, views.length - 1, resolveDebugViewLayout("single"))const runtime = createDebugPipelineRuntime( scene, camera, plan, resolveDebugViewLayout("single"), renderer, createDebugViewUniforms(),)See Native Runtime for the full frame loop.
import { float, vec4 } from "three/tsl"import { createCustomDebugView, DEFAULT_DEBUG_VIEWS,} from "threejs-debug-view"import { DebugViews } from "threejs-debug-view/r3f"
const fresnelView = createCustomDebugView({ id: "shader:fresnel", label: "Fresnel", node: vec4(float(1), float(0), float(0), float(1)),})
<DebugViews views={[...DEFAULT_DEBUG_VIEWS, fresnelView]} />The viewport render graph uses the stable id in pass keys.
The compose runtime also includes custom node identity in its pipeline key, so replacing a custom node instance with the same label/source still rebuilds the pipeline instead of rendering stale shader code.