Utilities

  • 04boilerplateFree
  • 02color
  • 01noise
  • 12postprocessing
  • 06patterns
  • 03distortion
  • 02sdf
  • 06function
  • 04interactivityNew

Join waitlist ↵

Boilerplate Project

Full project boilerplate for creative coding with React Three Fiber and WebGPU. Everything you need to start building.

Loading...
WebGPU Scene→
→

Boilerplate Project141

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...
Sketches141
Writing29

Fragments

Learn creative coding with shaders. For design engineers, creative coders and shader artists: techniques, tools, deep dives. Powered by ThreeJS and TSL.

Loading...

2025 Phobon

phobon.ioShadercraft

Pages

HomeTechniquesUtilitiesBreakdownsSketchesWriting

Contact

X @thenoumenonhey@fragments.supplyOKAY DEV @phobon
All rights reserved.

What is it?

This is a boilerplate project intended to drop into any React project to get you started with a React Three Fiber project, WebGPU and Three.JS (TSL).

React Three Fiber (R3F)

  • WebGPU SceneWebGPU scene boilerplate for React Three Fiber creative coding projects. Jump straight into building with TSL shaders.
  • Sketch ComponentTemplate React component for building creative coding sketches with Three.js and TSL. Copy, paste, start creating.

Once a React project is created, you can drop this entire file into your project to get a basic full screen WebGPU scene. If you're using the Fragments Boilerplate Github Repo, this will already be set up.

An example using the WebGPUScene component
import { Canvas, useThree } from '@react-three/fiber'
import { AdaptiveDpr, OrthographicCamera, Preload, StatsGl } from '@react-three/drei'
import { useState, useEffect } from 'react'
import { WebGPURenderer, LinearSRGBColorSpace, NoToneMapping } from 'three/webgpu'
 
type SceneProps = {
  debug?: boolean
  frameloop?: 'always' | 'demand' | 'never'
} & any
 
/**
 * ColorSpaceCorrection
 *
 * Sets the renderer's outputColorSpace to LinearSRGBColorSpace and disables tone mapping.
 * Ensures correct color output for WebGPU rendering.
 *
 * @returns {null}
 */
const ColorSpaceCorrection = () => {
  const { set } = useThree((state) => state)
 
  useEffect(() => {
    set((state) => {
      const _state = { ...state }
      _state.gl.outputColorSpace = LinearSRGBColorSpace
      _state.gl.toneMapping = NoToneMapping
      return _state
    })
  }, [])
 
  return null
}
 
/**
 * WebGPUScene
 *
 * Renders a three.js scene using the WebGPURenderer inside a @react-three/fiber Canvas.
 *
 * @param {SceneProps} props - Scene configuration props
 * @param {boolean} [props.debug=false] - Show WebGL stats overlay
 * @param {'always'|'demand'|'never'} [props.frameloop='always'] - Canvas render loop mode
 * @param {boolean} [props.orthographic=false] - Use orthographic camera (not currently used)
 * @param {React.ReactNode} props.children - Scene children
 * @returns {JSX.Element}
 *
 * Notes:
 * - Uses WebGPURenderer (three.js) for next-gen rendering
 * - Handles color space and tone mapping for WebGPU
 * - Preloads assets and adapts DPR
 */
const WebGPUScene = ({ debug = false, frameloop = 'always', orthographic = false, children, ...props }: SceneProps) => {
  const [canvasFrameloop, setCanvasFrameloop] = useState<'always' | 'demand' | 'never'>('never')
 
  return (
    <Canvas
      id='__webgpucanvas'
      {...props}
      frameloop={canvasFrameloop}
      gl={async (props) => {
        const renderer = new WebGPURenderer(props as any)
 
        await renderer.init()
        setCanvasFrameloop(frameloop)
 
        return renderer
      }}
    >
      <Preload all />
 
      <AdaptiveDpr />
 
      {children}
 
      <ColorSpaceCorrection />
 
      {debug ? <StatsGl className='fragments-supply__statsgl' /> : null}
 
      <OrthographicCamera makeDefault position={[0, 0, 1]} />
    </Canvas>
  )
}
 
const App = () => {
  const ref = useRef<any>(null)
 
  return (
    <section
      style={{
        width: '100vw',
        height: '100vh',
      }}
      ref={ref}
    >
      <Suspense fallback={null}>
        <WebGPUScene
          style={{
            position: 'fixed',
            inset: 0,
            pointerEvents: 'none',
          }}
          eventSource={ref}
          eventPrefix='client'
        ></WebGPUScene>
      </Suspense>
    </section>
  )
}
 
// Render the app
const rootElement = document.getElementById('root')!
if (!rootElement.innerHTML) {
  const root = ReactDOM.createRoot(rootElement)
  root.render(
    <StrictMode>
      <App />
    </StrictMode>,
  )
}

Using the Sketch Component

From here, you can add any components you want to your scene. Here we're going to use the WebGPUSketch component to render a full size sketch.

Here we're adding this into our App component.

Adding a WebGPUSketch component to the scene
/**
 * WebGPU sketch mesh.
 * @param {Object} props
 * @param {NodeRepresentation} [props.colorNode] - Node for color, defaults to vec3(uv, sin(time)).
 * @returns {JSX.Element}
 */
const WebGPUSketch = ({ colorNode }) => {
  const s = new MeshBasicNodeMaterial({ transparent: true })
  const _uv = uv()
 
  const _colorNode = colorNode ? colorNode : vec3(_uv, sin(time))
  s.colorNode = _colorNode
 
  const { width, height } = useThree((state) => state.viewport)
 
  return (
    <mesh material={s} scale={[width, height, 1]}>
      <planeGeometry args={[1, 1]} />
    </mesh>
  )
}
 
const App = () => {
  const ref = useRef<any>(null)
 
  const colorNode = Fn(() => vec3(uv(), oscSine(time.mul(0.5))))
 
  return (
    <section
      style={{
        width: '100vw',
        height: '100vh',
      }}
      ref={ref}
    >
      <Suspense fallback={null}>
        <WebGPUScene
          style={{
            position: 'fixed',
            inset: 0,
            pointerEvents: 'none',
          }}
          eventSource={ref}
          eventPrefix='client'
        >
          <WebGPUSketch colorNode={colorNode()} />
        </WebGPUScene>
      </Suspense>
    </section>
  )
}

Vanilla Javascript

If you have a vanilla javascript project, you can drop this entire file into your project to get a basic full screen WebGPU scene. If you're using the Fragments Vanilla Boilerplate Github Repo, this will already be set up with a basic router.

A basic Three.js scene
import {
  WebGPURenderer,
  MeshBasicNodeMaterial,
  PlaneGeometry,
  Scene,
  Mesh,
  OrthographicCamera,
  DoubleSide,
  NoToneMapping,
  LinearSRGBColorSpace,
} from 'three/webgpu'
import { Fn, uv, sin, time, vec3 } from 'three/tsl'
 
// Canvas
const canvas = document.querySelector('#webgpu-canvas')
 
const scene = new Scene()
 
// Sketch geometry
const sketchGeometry = new PlaneGeometry(1, 1, 1, 1)
 
// Sketch material
const sketchMaterial = new MeshBasicNodeMaterial({
  transparent: true,
  side: DoubleSide,
  depthWrite: false,
})
 
// Basic sketch node
const colorNode = Fn(() => vec3(uv(), sin(time.mul(0.5))))
sketchMaterial.colorNode = colorNode()
 
// Add a fullscreeen sketch plane to the scene
const sketch = new Mesh(sketchGeometry, sketchMaterial)
sketch.scale.set(2, 2, 1)
scene.add(sketch)
 
// Viewport sizes
const viewport = {
  width: window.innerWidth,
  height: window.innerHeight,
}
 
window.addEventListener('resize', () => {
  // Update sizes
  viewport.width = window.innerWidth
  viewport.height = window.innerHeight
 
  // Update camera
  camera.aspect = viewport.width / viewport.height
  camera.updateProjectionMatrix()
 
  // Update renderer
  renderer.setSize(viewport.width, viewport.height)
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})
 
// Camera
const camera = new OrthographicCamera(-1, 1, 1, -1, 0.1, 100)
camera.position.z = 1
scene.add(camera)
 
// Renderer
const renderer = new WebGPURenderer({
  canvas: canvas,
  antialias: true,
  toneMapping: NoToneMapping,
  outputColorSpace: LinearSRGBColorSpace,
})
renderer.setSize(viewport.width, viewport.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
renderer.setClearColor('#000000')
 
const frame = () => {
  renderer.renderAsync(scene, camera)
  window.requestAnimationFrame(frame)
}
 
frame()

Links to additional resources

  • Fragments R3F Boilerplate Github Repo
  • Fragments Vanilla Boilerplate Github Repo
Genuary 1

Genuary 1

Genuary 2

Genuary 2

Genuary 3

Genuary 3

Genuary 4

Genuary 4

Genuary 5

Genuary 5

Genuary 6

Genuary 6

Genuary 8

Genuary 8

Genuary 9

Genuary 9

Genuary 10

Genuary 10

Genuary 11

Genuary 11

Genuary 12

Genuary 12

Genuary 13

Genuary 13

Genuary 14

Genuary 14

Genuary 15

Genuary 15

Genuary 16

Genuary 16

Genuary 17

Genuary 17

Genuary 18

Genuary 18

Genuary 19

Genuary 19

Genuary 20

Genuary 20

Genuary 22

Genuary 22

Genuary 23

Genuary 23

Genuary 24

Genuary 24

Genuary 25

Genuary 25

Genuary 26

Genuary 26

Genuary 27

Genuary 27

Genuary 28

Genuary 28

Genuary 29

Genuary 29

Genuary 30

Genuary 30

Genuary 31

Genuary 31

Flare 1

Flare 1

Free
Flare 2

Flare 2

Flare 3

Flare 3

Flare 4

Flare 4

Flare 5

Flare 5

Flare 6

Flare 6

Flare 7

Flare 7

Flare 8

Flare 8

Flare 9

Flare 9

Eidolon 1

Eidolon 1

Eidolon 2

Eidolon 2

Eidolon 3

Eidolon 3

Eidolon 4

Eidolon 4

Eidolon 5

Eidolon 5

Dawn 1

Dawn 1

Free
Dawn 2

Dawn 2

Dawn 3

Dawn 3

Dawn 4

Dawn 4

Dawn 5

Dawn 5

Arcs 1

Arcs 1

Arcs 2

Arcs 2

Arcs 3

Arcs 3

Arcs 4

Arcs 4

Arcs 5

Arcs 5

Arcs 6

Arcs 6

Imaginary 1

Imaginary 1

Imaginary 2

Imaginary 2

Imaginary 3

Imaginary 3

Imaginary 4

Imaginary 4

Imaginary 5

Imaginary 5

Imaginary 6

Imaginary 6

Imaginary 7

Imaginary 7

Imaginary 8

Imaginary 8

Mesh 7

Mesh 7

Mesh 8

Mesh 8

Fundament

Fundament

Cellular

Cellular

Network

Network

Spiral

Spiral

Monde

Monde

Concentric

Concentric

Flow

Flow

Shift 1

Shift 1

Shift 2

Shift 2

Shift 3

Shift 3

Shift 4

Shift 4

Shift 5

Shift 5

Shift 6

Shift 6

Shift 7

Shift 7

Shift 8

Shift 8

Cascade 1

Cascade 1

Cascade 2

Cascade 2

Cascade 3

Cascade 3

Cascade 4

Cascade 4

Cascade 5

Cascade 5

Cascade 6

Cascade 6

Cascade 7

Cascade 7

Cascade 8

Cascade 8

Cascade 9

Cascade 9

Cascade 10

Cascade 10

Abiogenic 1

Abiogenic 1

Abiogenic 2

Abiogenic 2

Abiogenic 3

Abiogenic 3

Abiogenic 4

Abiogenic 4

Abiogenic 5

Abiogenic 5

Warp 1

Warp 1

Warp 2

Warp 2

Warp 3

Warp 3

Warp 4

Warp 4

Warp 5

Warp 5

Gravity 1

Gravity 1

Gravity 2

Gravity 2

Gravity 3

Gravity 3

Gravity 4

Gravity 4

Gravity 5

Gravity 5

Gravity 6

Gravity 6

Gravity 7

Gravity 7

Gravity 8

Gravity 8

Gravity 9

Gravity 9

Gravity 10

Gravity 10

Slate 1

Slate 1

Slate 2

Slate 2

Slate 3

Slate 3

Slate 4

Slate 4

Slate 5

Slate 5

Bands 1

Bands 1

Bands 2

Bands 2

Bands 3

Bands 3

Bands 4

Bands 4

Bands 5

Bands 5

Bands 6

Bands 6

Bands 7

Bands 7

Genuary 1

Genuary 1

Genuary 2

Genuary 2

Genuary 3

Genuary 3

Genuary 4

Genuary 4

Genuary 5

Genuary 5

Genuary 6

Genuary 6

Genuary 7

Genuary 7

Genuary 8

Genuary 8

Genuary 12

Genuary 12

Genuary 13

Genuary 13

Genuary 14

Genuary 14

Genuary 17

Genuary 17

Genuary 19

Genuary 19

Genuary 20

Genuary 20

Genuary 21

Genuary 21

Genuary 23

Genuary 23

Genuary 24

Genuary 24

Genuary 25

Genuary 25

Genuary 27

Genuary 27

Genuary 30

Genuary 30

Be the first to know what's next