Live data from Hacker News

React Renderer for Three.js

github.com

41–50 of 136 posts

Re: React Renderer for Three.js

#41

Earlier quoted context omitted.

It's interesting because in normal React usage, the overhead of generating and throwing away a bunch of objects on each update is dwarfed by the cost of updates to the DOM But in Three.JS the actual updates to the tree should be cheap, right? There's no reflow, you're just setting values in memory to be used by the next render frame. If so, that changes the calculus. There's also the fact that in an app, it's rare fo…

Yeah, I can totally see the argument that it's a programming model that's well understood and you can get a productivity boost from that. However I don't think you can say that doesn't come with a cost, otherwise it would have been pretty widely adopted across the industry.

> otherwise it would have been pretty widely adopted across the industry

I'm not sure that's a fair explanation for why. It's totally possible to come up with new paradigms that are useful even though nobody's thought of them before.

I would think the main issue will be around JavaScript's tendency (cultural, syntactic, etc) to casually create and release objects all over the place, constantly. There's nothing intrinsically wrong with this, but it seems problematic for this use-case.

Example: JavaScript doesn't have named function parameters, because instead you just create and destructure an object:

  function foo({ param1, param2, param3 }) {
  }

  foo({ param1: 'a', param2: 'b', param3: 'c' })
The syntax encourages this, the React docs encourage this. JSX itself does this for every element you render. And for normal JavaScript usecases it works just fine. But when you're running this logic every frame, I would guess it will limit you at a certain point.

Despite that, I think people are onto something with the broader idea of coding a 3D scene declaratively. I'm just skeptical that React or its norms are the right path to doing it at scale.

Re: React Renderer for Three.js

#42

Earlier quoted context omitted.

react has little to do with html. it just calls functions, what you see in react-dom isn't html either, these are nested document.createElement(...) calls. this can be configured for any platform, web, native or otherwise, so in this case is just new THREE.Mesh(). in react terms it's called a custom renderer. the other thing you say, that react is bad for animations — r3f operates outside of react, there is no overhe…

So again, I have to contest this. Not all UIs should be described in a tree structure. React and it’s whole diffing algo is to make sense of parts of the tree that changed. That idea didn’t come out of the blue, it came from html, it came from the DOM. If I give you a blank sheet of paper and say ‘write me a rendering api’, and you immediately reach for a tree structure, I’d be compelled to say you are influenced by…

hard to read through all that tbh. i mostly do not understand what you are talking about when threejs is clearly a tree that react expresses with complete ease. groups in groups with meshes, which have materials, etc. it seems to me you have not worked with threejs before. r3f just expresses threejs, in the same exact same shape you'd have in an imperative app.

there are dozens, hundreds of demos now that are testament to this approach: https://docs.pmnd.rs/react-three-fiber/getting-started/examp... this is slowly becoming the norm of how you write a 3d app or game.

Re: React Renderer for Three.js

#43
post #28

Earlier quoted context omitted.

While I strongly suspect you’re right about React being influenced by the problem space, I’d contest the notion that trees aren’t useful for computational constructs in general. Trees are fundamental to the concept of a function call graph over time, for example.

In most production renderers, you have a soup of objects. Sometimes it's a tree, but much more often it's a graph of nodes pointing to each other. One of the first steps of this is to gather all the nodes in the graph, flattening it into a list, and then start filtering and sorting it: for every opaque object, you likely toss it in Z-pre and opaque buckets (for objects visible through the main frustum), and a shadow…

it does not take a dom-equivalent tree, it just expresses the same code you would write out imperatively in a declarative way. threejs is a nested graph after all.

Re: React Renderer for Three.js

#44
post #12

Earlier quoted context omitted.

you can't express a 3d scene with markup alone, that is why VRML didn't succeed. the JSX you see just masks function calls, it is not XML or HTML, but the true power is in components and hooks (useFrame, etc). a r3f component is self-contained, it will even subscribe to the render-loop. click into these two examples to see the difference: https://twitter.com/0xca0a/status/1426924274527477764

> you can't express a 3d scene with markup alone What?

you want your view to do something, to participate in the render loop, to animate, user interaction etc. look at the example on the main page: https://github.com/pmndrs/react-three-fiber#what-does-it-loo...

Re: React Renderer for Three.js

#45
post #32

Is there an error in the examples? You have const mesh = useRef() ... You'll be rendering an undefined element (before the ref has a chance to attach). Also, the TypeScript example makes me head hurt. const ref = useRef(null!) Ah, yes. A non-null null literal.

I'm guessing they are overloading the ref's usage with the custom renderer. I believe that a renderer can accept non-function/class components in theory, which is why this works. I don't really like this though, although interesting, it feels like a hack and might not integrate well with tooling (e.g. the Typescript example). How I would have implemented it was exposition a Mesh component which wraps this, and a useM…

Yeah, I don’t have experience with this lib, but the example code looks overly magic. But I’m also more of a backend dev, and find the useRef API to be inherently confusing, so that’s probably part of it.

Re: React Renderer for Three.js

#46
post #32

Is there an error in the examples? You have const mesh = useRef() ... You'll be rendering an undefined element (before the ref has a chance to attach). Also, the TypeScript example makes me head hurt. const ref = useRef(null!) Ah, yes. A non-null null literal.

this is how refs work. it's the same with a div. the ref will be filled in useEffect, not before.

null! is a common typescript thing, it is a semantic guarantee that the ref is static and hence will be available. this saves you the if (ref.current) { ... } check.

Re: React Renderer for Three.js

#47
post #13

Earlier quoted context omitted.

The creator of React-Three-Fiber has come out with some extremely bizarre tweets, like claiming updating 2,000 cubes at 60fps is an "impossible amount of load" [0]. The solution it uses for performance is... punting your calculations to the next frame if you didn't make it this frame. They call this "the scheduler". Turns out this makes no sense in any serious context if you want your 3D frame to be coherent. I'm sur…

as absurd as it may seem to you, this is a react feature. the upcoming react 18 release is pretty much based on concurrency. this is the test you are referring to: https://docs.pmnd.rs/react-three-fiber/advanced/scaling-perf... the github repo now contains a vanilla test that you can run

As I said, "schedule" just means "defer work to future frames". That's a valid strategy if you have severe load, but it's not globally applicable: one might imagine that two components need to be updated together (e.g. updating the arms and body of a character should not be split up between two frames, or else the user will see split bodies for in-between frames). At the very best, this sort of scheduling should be informed by gameplay systems.

It can "effortlessly outperform" only if we're talking about throughput, not latency here -- the scheduler ensures that less is done each frame so we can meet 60fps each frame, at the expense of having things done frames later than when they probably should have been.

I'm aware this is all a React feature. I disagree with the React team that "concurrency" is a usable solution to performance in all cases. But I can respectfully disagree with them about that. I can understand why a scheduler helps improve user-perceived performance. I'm happy to talk about what I believe are the tradeoffs.

Regardless of all of that, updating 2,000 cubes should never cause 700ms of load to begin with. The test you linked me to is not the same test. The test in the tweet is seen here [0], and has no artificial runtime delay as far as I can tell. For extra irony, note that they already have to bypass React (which is described as ItemSlow), in favor of the "Zustand approach", aka modifying things imperatively.

Remember, Three.JS is already running every frame, and rendering every frame, with or without a scheduler. That means that the 700ms overhead has to be coming from the React / R3F part of the demo.

[0] https://github.com/pmndrs/react-three-fiber/blob/e3a71baad42...

Re: React Renderer for Three.js

#48
post #30

Earlier quoted context omitted.

I can't take a 3d rendering framework seriously if it gets bogged down at updating 2000 untextured and non-interacting cubes @ 60 FPS. What on earth is all that time spent on? Doing ~2000 3x3 matrix ops should take a modern processor a few hundred usec surely? To put the silliness of the 2000 number in context, look here at a showcase of the Unity ECS system from years (!) ago: https://software.intel.com/content/www/…

You have to remember that this 700ms overhead is not the renderer. It's just setting fields on the underlying Three.JS Cube objects. The Three.JS renderer runs fine, and I don't even consider Three.JS to be a fast renderer. So yes, the overhead of React-Three-Fiber's tree reconciliation is seemingly massive. No, I do not have any answers for what it is doing. Nor do I have any guesses.

there were multiple versions of that test, the fist had nothing to do with the subject matter, the ones that people refer to (spinning cubes) had an artificial delay that was added to simulate cpu stress.

Re: React Renderer for Three.js

#49
post #32

Is there an error in the examples? You have const mesh = useRef() ... You'll be rendering an undefined element (before the ref has a chance to attach). Also, the TypeScript example makes me head hurt. const ref = useRef(null!) Ah, yes. A non-null null literal.

this is how refs work. it's the same with a div. the ref will be filled in useEffect, not before. null! is a common typescript thing, it is a semantic guarantee that the ref is static and hence will be available. this saves you the if (ref.current) { ... } check.

The ref isn't used in an effect, though, at least not in the provided code.

Re: React Renderer for Three.js

#50
post #5

When AR/VR finally happens, UI developers will have to deal with complexity from a completely different paradigm. For me, React's biggest strength has always been its ability to organize complexity into a manageable order. Combine this with the large pool of developers and extensive ecosystem, I think React will be the go-to tool for AR/VR apps. For this reason, I'm super hyped for R3F.

Totally agree!

We switched https://flux.ai from vanilla ThreeJS to R3F and it’s been a huge productivity gain for the whole team!

Less code, that is more capable and more reusable!

In case anyone is interested, we are hiring: https://coda.io/@flux-ai/flux-jobs

Post reply on HN