Coder Social home page Coder Social logo

Comments (8)

gkjohnson avatar gkjohnson commented on June 1, 2024 2

I don't think I'd call this a memory leak - this from an intermediary render target used internally for rendering transmissive materials. It's only created once it's needed and kept around to render any transmissive materials in the future. Unless there's a problem demonstrated I don't know if I feel this needs a hook to enable disposal.

from three.js.

Mugen87 avatar Mugen87 commented on June 1, 2024 1

It works well for me. What are the pitfalls?

Certain WebGL context and WebXR event listener are removed and not added again when you continuing using the renderer. These listeners are added only once during the construction time.

If it works you, that's fine. However, keep in mind the usage is not officially supported.

from three.js.

deenns avatar deenns commented on June 1, 2024

This is at least confusing. Because of this behavior renderer.info.memory cannot be used to check that all resources are properly disposed - sometimes the hidden texture is created, sometimes not - it depends on a model.

It would be ok, if it were disposed when renderer.dispose() is called, but it's not so. And in case of an SPA with a model viewer on a certain page, we need to completely dispose of all Three.js resources, once that page is closed. And once it's opened again, everything will be created from scratch (the old renderer will not be reused).

from three.js.

gkjohnson avatar gkjohnson commented on June 1, 2024

This is at least confusing. Because of this behavior renderer.info.memory cannot be used to check that all resources are properly disposed - sometimes the hidden texture is created, sometimes not - it depends on a model.

I'll have to leave this to someone else. I agree it's confusing but correctly tracking all internal textures, materials, and shaders as separate from users to keep these fields up to date may be complicated and not worth the effort.

It would be ok, if it were disposed when renderer.dispose() is called, but it's not so.

This is due to a race condition in the "dispose" function. The transmission texture has already been disposed when all textures are deallocated so the value is not decremented. The same will happen with other textures if you don't dispose of them explicitly before calling "renderer.dispose", though, leaving all values as they were even though all objects have been disposed of. The three.js renderer is not designed or intended to be used again once dispose has been called.

And in case of an SPA with a model viewer on a certain page, we need to completely dispose of all Three.js resources, once that page is closed. And once it's opened again, everything will be created from scratch (the old renderer will not be reused).

Calling "renderer.dispose" is enough to dispose of all resources on the WebGL context. There is no need to call dispose on every individual object - mostly. The exception is if you're rendering the same objects with multiple renderers which will cause "dispose" callbacks to accumulate (see #20698) but this does affect gpu memory.

from three.js.

deenns avatar deenns commented on June 1, 2024

The three.js renderer is not designed or intended to be used again once dispose has been called.

I thought that (docs)

What happens when I call dispose() and then use the respective object at a later point?
The deleted internal resources will be created again by the engine. So no runtime error will occur but you might notice a negative performance impact for the current frame, especially when shader programs have to be compiled.

is related to all Three.js objects including the renderer, and it's completely safe to call renderer.dispose() many times, e.g. when a model is changed, but the viewer isn't completely recreated. Are there any pitfalls?

Calling "renderer.dispose" is enough to dispose of all resources on the WebGL context. There is no need to call dispose on every individual object - mostly.

That's good, I will keep it in mind. However, I suspect that it doesn't dispose ImageBitmaps which are used by default for all textures in GLB files. So I still will have to traverse the scene as it's done in the disposeScene function.

from three.js.

Mugen87 avatar Mugen87 commented on June 1, 2024

I thought that (docs)

Calling WebGLRenderer.dispose() is indeed intended for the use case that the renderer isn't used anymore. Using it after the call of dispose() is invalid. Maybe it's best to clarify this in the guide although it is already mentioned here: https://threejs.org/docs/#api/en/renderers/WebGLRenderer.dispose

The renderer can create internal resources for certain operations and this can be visible in the renderer.info object. As long as these objects are not counting up and allocating more and more memory, this is not considered as a memory leak.

from three.js.

Mugen87 avatar Mugen87 commented on June 1, 2024

There is of course the option to "hide" internal resources in renderer.info. However, this creates confusion for all devs who track WebGL resources with external tools (which ends up in mismatches with what three.js reports).

from three.js.

deenns avatar deenns commented on June 1, 2024

However, this creates confusion for all devs who track WebGL resources with external tools (which ends up in mismatches with what three.js reports).

It creates confusion now as well. Isn't it possible to just decrement it properly when the resource is released?

Calling WebGLRenderer.dispose() is indeed intended for the use case that the renderer isn't used anymore

It works well for me. What are the pitfalls? Actually, it would be rather convenient if you make it a standard, so that all Three.js object behave the same way. If it's not possible, then, of course, it should be mentioned explicitly on the docs page as an exception.

from three.js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.