-
-
Notifications
You must be signed in to change notification settings - Fork 36.2k
Description
Description of the problem
I have a lot of effects on my ThreeJS scenes. Right now with the way ThreeJS's effects are designed, they each allocate their own render targets, even their intermediate/temporary render targets. This leads to somewhere around 50 render targets allocated for my specific use case. But really only a couple are ever used at the same time, the rest are just setting there wasting memory and causing out of memory errors are various devices, especially high resolution (QHD/4K) + low memory mobile devices.
I am thinking that if we create a memory pool ( https://en.wikipedia.org/wiki/Memory_pool ) for RenderTargets we could decrease the maximum amount of memory required for complex EffectComposer pipelines without sacrificing speed or quality.
The design would be something like:
RenderTargetPool:
allocate( width, height, options ) -> renderTarget;
free( renderTarget )
nextFrame() - increase current frame.
disposeOld( oldness ) - to dispose all targets not recently used (could be all)
disposeAll() -- to be called once done or in the case of a resize (see below.)
This memory pool would track which render targets are currently in use (which haven't been returned) and allocate new ones if needed. But it would try to recycle as much as possible. I'd keep it simple and track the current frame and allow explicit disposal of those render targets that haven't been used in a recent frame (specified by the user - but I think a value of 10 is pretty reasonable for most use cases) or all current render targets (if ending the rendering.)
This will automatically minimally allocate render targets.
I guess the only issue is how to handle resizes. Right now ThreeJS will resize render targets when the render region changes shape. I wonder if we adopt the RenderTargetPool we could just dispose all in that case and recreate render targets of the new size -- I think that is how it works underneath anyhow.
Only intermediate render targets can be used via the pool. Those that persist such those that back up textures attached to objects need to have explicitly controlled lifetimes.
Thoughts welcome.... this is just an idea on how to solve our issue while making Three.JS easier and more efficient.
Three.js version
- Dev
- r84
Browser
- All of them
OS
- All of them