
Show HN: Three and React = react-three-fiber, a new renderer based on Fiber - mlsarecmg
https://github.com/drcmda/react-three-fiber
======
Stevvo
Doesn't seem like a great fit. Immutability is a waste of memory when working
with complex 3D scenes and React is already pretty processor and memory heavy.

~~~
mlsarecmg
Would help in the same way that react-dom helps the dom, especially
performance. React basically manages the scene, only updating the parts that
change. As for processor speed, React only mounts/unmounts, it maintains
THREEs performance otherwise. In the demo for instance there are two
animations, the stars are driven by the render loop (outside of react) and the
thing in the middle using react-spring, which also animates outside of react.

I think the performance increase for a large project with a complex scene
graph could be drastic compared to handling it manually - just like vanilla js
would not easily get even with react unless you implement change detection,
read/write queues, etc. With react-fibers scheduling the difference will only
get larger since now it can bail out of or defer actions that would blow the
60fps frame budget.

As for memory and immutability, the actual v-dom tree is next to nothing, a
node is a couple of bytes. This is the same as for a huge dom UI app with
millions of divs and spans and table fields. The logical tree never hurts. One
big problem with THREE has always been garbage and the object overhead - it's
super easy to create leaks or create objects needlessly

    
    
        mesh.position.copy(xyz.clone())
    

I've been doing three for a couple of years now and to not be wasteful takes
_a lot_ of discipline as basically everything nudges you into re-creating
objects since re-use can have unexpected side-effects. With the reconciler you
can stow away objects into the graph, which means they're managed. Probably
will reduce the memory footprint in the end, even with a v-dom on top.

------
cannedslime
Cool! But why and when? How would I use loaders with this? (GLTF etc)

~~~
mlsarecmg
You would use them as you always did. You have raw access to everything. But
if you want loading results to be managed, put them into useEffect/useMemo and
render out the results. For instance i've just made a text-sprite component
that looks like this:

    
    
        function Text({ children, ...props }) {
          const { camera, size, viewport } = useThree()
          const { width } = viewport()
          const canvas = useMemo(() => {
            const canvas = document.createElement('canvas')
            canvas.width = canvas.height = size.width * 2
            const context = canvas.getContext('2d')
            context.font = `bold ${size.width *
              0.45}px -apple-system, BlinkMacSystemFont, avenir next, avenir, helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif`
            context.textAlign = 'center'
            context.fillStyle = 'black'
            context.fillText(children, size.width, size.height + size.width * 0.4)
            return canvas
          }, [children, size.width])
          return (
            <sprite scale={[width, width]} {...props}>
              <spriteMaterial name="material">
                <canvasTexture name="map" image={canvas} premultiplyAlpha onUpdate={s => (s.needsUpdate = true)} />
              </spriteMaterial>
            </sprite>
          )
        }

