【问题标题】:THREE.js webGL garbage collection三.js webGL 垃圾回收
【发布时间】:2014-01-23 01:45:37
【问题描述】:

我们有一个使用 THREE.js 渲染身体网格的 3D 图像的应用。我们有一个名为 MeshViewer 的对象,它封装了渲染功能;在初始化方法中,我们设置了

this.renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true })

我们编写了一个脚本来测试 this.renderer 没有被释放。

<script>
    var count = 0;
    function loop () {
        if (count >= 25) { 
            return; 
        }
        else {
            count++;
            var viewer = new MeshViewer(
                'mesh_viewer',
                's3_assets/textured_mean_scape_female.obj',
                []
            );

            viewer.cleanup();

            setTimeout(function () {
                loop();
            }, 500);
        }
    }
    loop();
</script>

在这种情况下,'mesh_viewer' 是我们想要嵌入查看器的 DOM 元素的 id。我们的清理方法集

this.renderer = null

清理工作,从某种意义上说,如果我们不执行清理,我们会得到一个错误,即存在太多活动的 WebGL 上下文,我们无法再创建,如果我们清理,我们不会得到那个错误。

我的问题是,为什么在 setTimeout 循环之前调用 viewer.cleanup 时会失败,而在 setTimeout 之外调用 cleanup 时会通过? (这可能是一个 JavaScript 问题,而不是 THREE.js/WebGL 问题。)

【问题讨论】:

  • 为什么这个问题被否决了?
  • 是否有任何控制台错误?
  • 也许传递给 setTimeout 的函数捕获了查看器及其所有属性,包括渲染器,这意味着渲染器的引用计数永远不会变为 0,因此不会被垃圾回收?

标签: javascript three.js webgl


【解决方案1】:

可能与the way a browser executes javascript and other stuff in a single thread有关。

如果您将viewer.cleanup(); 放在setTimeout 之前,浏览器的内部函数或三个延迟函数将在调用loop(); 之前找到时间实际释放渲染器。

否则 viewer.cleanup();loop() 将被连续调用,中间没有时间让其他任何事情发生。

注意:我没有做任何测试来确认


还有一个建议:也许您应该将您的 THREE.WebGLRenderer 实例放入单例中并重用它而不是释放它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 2012-01-28
    • 2013-06-27
    • 2011-11-29
    • 2021-12-20
    • 2011-07-15
    • 2014-03-09
    相关资源
    最近更新 更多