You're viewing the v10 deployment.

Render Targets

useRenderTarget creates a framebuffer (FBO) that matches the active renderer — a WebGL target or a WebGPU RenderTarget

useRenderTarget creates a render target (FBO) that is automatically the correct type for the current renderer. With v10's dual-renderer support you no longer have to pick the class yourself.

Why this matters

Three.js uses different render target classes per renderer:

  • WebGLRenderTarget for the WebGL renderer
  • RenderTarget for the WebGPU renderer

useRenderTarget returns the right one for the active renderer, so the same component works against either.

Basic usage

import { useRenderTarget, useFrame } from '@react-three/fiber'

function PortalScene() {
  const fbo = useRenderTarget(512, 512, { depthBuffer: true, samples: 4 })

  useFrame(({ renderer, scene, camera }) => {
    renderer.setRenderTarget(fbo)
    renderer.render(scene, camera)
    renderer.setRenderTarget(null)
  })

  return (
    <mesh>
      <planeGeometry />
      <meshBasicMaterial map={fbo.texture} />
    </mesh>
  )
}

Argument forms

The hook accepts several patterns. With no size, it uses the canvas dimensions (and resizes with the canvas).

// canvas size (resizes with canvas)
const fbo = useRenderTarget()

// canvas size with options
const fbo = useRenderTarget({ samples: 4 })

// square render target (512×512)
const fbo = useRenderTarget(512)

// square render target with options
const fbo = useRenderTarget(512, { depthBuffer: true })

// explicit dimensions
const fbo = useRenderTarget(512, 256)

// explicit dimensions with options
const fbo = useRenderTarget(512, 256, { samples: 4 })

Signatures

// canvas size (defaults to canvas dimensions)
useRenderTarget(options?: RenderTargetOptions): R3FRenderTarget

// square render target
useRenderTarget(size: number, options?: RenderTargetOptions): R3FRenderTarget

// explicit dimensions
useRenderTarget(width: number, height: number, options?: RenderTargetOptions): R3FRenderTarget

The return type R3FRenderTarget is WebGLRenderTarget | RenderTarget on @react-three/fiber, and narrows to the one class once the app registers its renderer or imports from a single-renderer entry (see Per-renderer type below).

Options

OptionTypeDefaultDescription
depthBufferbooleantrueCreate depth buffer
stencilBufferbooleanfalseCreate stencil buffer
samplesnumber0MSAA sample count
countnumber1MRT target count (WebGPU)
formatnumberRGBAFormatTexture format
typenumberUnsignedByteTypeData type
minFilternumberLinearFilterMinification filter
magFilternumberLinearFilterMagnification filter
generateMipmapsbooleanfalseGenerate mipmaps

Per-renderer type

The class you get back follows the renderer the Canvas loaded: a WebGLRenderTarget on WebGL, a RenderTarget on WebGPU. The hook constructs the target class carried by the root's renderer support (state.internal.support.RenderTarget), so it is always valid for the renderer in use without branching yourself.

Only the declared type differs:

  • @react-three/fiber: WebGLRenderTarget | RenderTarget (either renderer can be running). Register the renderer once and it narrows, with no cast, along with state.renderer and the rest (see Typing the renderer):

    declare module '@react-three/fiber' {
      interface Register {
        renderer: 'webgpu' // or 'webgl'
      }
    }
    
  • @react-three/fiber/legacy: WebGLRenderTarget.

  • @react-three/fiber/webgpu (deprecated): RenderTarget.