Closed nikitapilgrim closed 4 years ago
looks nice, but seems to me, like most workers i have seen, scaling it is messy. loaders, input events, etc. perhaps with a reconciler like r3f you could pull it off without causing that much damage. pointer input for instance is all predefined and could be transported into the worker.
you wanna give it a go?
then again, i see that most of the threejs logic is inside the worker. that essentially kills declarativity since now you're doing everything imperatively again. 🤔
in our projects we tree shake the hell out of threejs manually to about 50kb (https://github.com/react-spring/react-three-fiber/blob/master/recipes.md#reducing-bundle-size) and bundle splitting/suspense. that takes three out of the picture for the first load.
You could use @react-three/fiber
with OffscreenCanvas
with help of custom renderer.
In main thread create canvas and transfer it to the worker like this:
// main.jsx (main thread)
import React from "react"
export const Main = () => {
const canvasRef = React.useRef()
React.useEffect(() => {
const offscreen = canvasRef.current.transferControlToOffscreen()
const worker = new Worker('worker.js')
worker.postMessage({ canvas: offscreen }, [offscreen])
}, [])
return <canvas ref={canvasRef} />
}
Inside worker create custom WebGLRenderer with offscreen canvas passed to it. Then use this custom renderer as said in the docs like this:
// worker.jsx (worker thread)
import { createRoot } from '@react-three/fiber'
ctx.onmessage = (event) => {
const { canvas } = event.data
createRoot(canvas).render(<ReactThreeFiberComponent />)
}
that could work. in src/targets there are the building blocks for making render targets, for instance ResizeContainer, in which the the renderer is ramped up. you could try to wire this into a worker. although im sure it wont be so easy later on. pointer events, everything that has to sync between main and worker is going to be hell.
https://evilmartians.com/chronicles/faster-webgl-three-js-3d-graphics-with-offscreencanvas-and-web-workers Did you manage to implement it in your projects?