1

I'm working on a nonlinear editing animation system with Three.js as the 3D library. I'd like to render a sequence of frames to memory, then play the frames back at an arbitrary frame rate. The idea is that the scene might be too complex to render in real time, so I want to pre-render the frames, then play them back at the target fps. I don't necessarily need interactivity while the animation is playing, but it's important that I see it at full speed.

From these links (How to Render to a Texture in Three.js, Rendering a scene as a texture), I understand how to render to a framebuffer instead of the canvas. Can I store multiple framebuffers then render each of those to the canvas later at a smooth frame rate?

Community
  • 1
  • 1
Justin
  • 1,881
  • 4
  • 20
  • 40

2 Answers2

2

You can try one of the following:

Option a) capture canvas-content, playback as png-sequence (I didn't test that, but it sounds like it could work):

  • render to the canvas just as you always do
  • export the canvas as data-URL using canvas.toDataURL()
  • as huge dataURLs are often a problem with devtools, you might want to consider converting the data-urls to a blob: Blob from DataURL?
  • repeat for all frames
  • playback as png-sequence

Option b) using RenderTargets:

  • render scene to a render-target/framebuffer
  • use renderer.readRenderTargetPixels() to read the rendered result into memory (this returns basically a bitmap)
  • data can be copied into a 2d canvas ImageData instance

Option c) Using Rendertarget-Textures (no downloading from GPU):

  • render into a rendertarget and create a new one for each frame (there is very likely a limit on how many of them you can keep around, so this might not be the best solution)
  • image-data is stored on GPU and referenced via rendertarget.texture
  • use a fullscreen-quad textured with rendertarget.texture for playback. Only needs to rebind the textures for every playback-frame, so this would be the most efficient.
Community
  • 1
  • 1
Martin Schuhfuß
  • 6,814
  • 1
  • 36
  • 44
1

You can use canvas.captureStream() and mediaRecorder to record the scene and then save it. You can later play it as video later without caring about frame rate. You may miss some frames as it has its own performance overhead but it all depends on your use case.

Amritesh Anand
  • 893
  • 11
  • 22