Pmndrs.docs

Canvas

The Canvas object is your portal into three.js.

The Canvas object is where you start to define your React Three Fiber Scene.

import React from 'react'
import { Canvas } from '@react-three/fiber'

const App = () => (
  <Canvas>
    <pointLight position={[10, 10, 10]} />
    <mesh>
      <sphereBufferGeometry />
      <meshStandardMaterial color="hotpink" />
    </mesh>
  </Canvas>
)

Render Props

PropDescriptionDefault
childrenthree.js JSX elements or regular components
glProps that go into the default renderer, or your own renderer. Also accepts a synchronous callback like gl={canvas => new Renderer({ canvas })}{}
cameraProps that go into the default camera, or your own THREE.Camera{ fov: 75, near: 0.1, far: 1000, position: [0, 0, 5] }
shadowsProps that go into gl.shadowMap, can also be set true for PCFsoftfalse
raycasterProps that go into the default raycaster{}
frameloopRender mode: always, demand, neveralways
resizeResize config, see react-use-measure's options{ scroll: true, debounce: { scroll: 50, resize: 0 } }
orthographicCreates an orthographic camerafalse
dprPixel-ratio, use window.devicePixelRatio, or automatic: [min, max][1, 2]
legacyEnables THREE.ColorManagement.legacyMode in three r139 or laterfalse
linearSwitch off automatic sRGB encoding and gamma correctionfalse
eventsConfiguration for the event manager, as a function of stateimport { events } from "@react-three/fiber"
flatUse THREE.NoToneMapping instead of THREE.ACESFilmicToneMappingfalse
onCreatedCallback after the canvas has rendered (but not yet committed)(state) => {}
onPointerMissedResponse for pointer clicks that have missed any target(event) => {}

Render defaults

Canvas uses createRoot which will create a translucent THREE.WebGLRenderer with the following constructor args:

  • antialias=true
  • alpha=true
  • powerPreference="high-performance"

and with the following properties:

  • outputEncoding = THREE.sRGBEncoding
  • toneMapping = THREE.ACESFilmicToneMapping

It will also create the following scene internals:

  • A THREE.Perspective camera
  • A THREE.Orthographic cam if orthographic is true
  • A THREE.PCFSoftShadowMap if shadows is true
  • A THREE.Scene (into which all the JSX is rendered) and a THREE.Raycaster

In recent versions of threejs, THREE.ColorManagement.legacy will be set to false to enable automatic conversion of colors according to the renderer's configured color space. R3F will handle texture encoding conversion. For more on this topic, see https://threejs.org/docs/#manual/en/introduction/Color-management.

Custom Canvas

R3F can render to a root, similar to how react-dom and all the other React renderers work. This allows you to shave off react-dom (~40kb), react-use-measure (~3kb) and, if you don't need them, pointer-events (~7kb) (you need to explicitly import events and add them to the config otherwise).

Roots have the same options and properties as Canvas, but you are responsible for resizing it. It requires an existing DOM <canvas> object into which it renders.

CreateRoot

Creates a root targeting a canvas, rendering JSX.

import { createRoot, events } from '@react-three/fiber'

let root

const handleResize = () => {
  const size = { width: window.innerWidth, height: window.innerHeight }

  // Create root with a size, events
  root = createRoot(document.querySelector('canvas'), {
    events,
    size,
  })

  // Render JSX
  root.render(<mesh />)

  // Can also tweak root root options after creation:
  root.configure({ size })

  // Or to unmount and dispose of memory:
  root.unmount()
}
handleResize()

window.addEventListener('resize', handleResize)

// to unmount
root.unmount()

Tree-shaking

New with v8, the underlying reconciler no longer pulls in the THREE namespace automatically.

This enables a granular catalogue which also enables tree-shaking via the extend API:

import { extend, createRoot } from '@react-three/fiber'
import { Mesh, BoxGeometry, MeshStandardMaterial } from 'three'

extend({ Mesh, BoxGeometry, MeshStandardMaterial })

createRoot(canvas).render(
  <>
    <mesh>
      <boxGeometry />
      <meshStandardMaterial />
    </mesh>
  </>,
)

There's an official babel plugin which will do this for you automatically:

// In:

import { createRoot } from '@react-three/fiber'

createRoot(canvasNode).render(
  <mesh>
    <boxGeometry />
    <meshStandardMaterial />
  </mesh>,
)

// Out:

import { createRoot, extend } from '@react-three/fiber'
import { Mesh as _Mesh, BoxGeometry as _BoxGeometry, MeshStandardMaterial as _MeshStandardMaterial } from 'three'

extend({
  Mesh: _Mesh,
  BoxGeometry: _BoxGeometry,
  MeshStandardMaterial: _MeshStandardMaterial,
})

createRoot(canvasNode).render(
  <mesh>
    <boxGeometry />
    <meshStandardMaterial />
  </mesh>,
)