我们有一个应用程序使用 THREE.js 渲染 body 网格的 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 外部和之前调用清理时会通过? (这可能是一个 JavaScript 问题,而不是一个 THREE.js/WebGL 问题。)
最佳答案
可能与the way a browser executes javascript and other stuff in a single thread有关.
如果您将 viewer.cleanup();
放在 setTimeout
之前,浏览器的内部函数或三个延迟函数将在调用之前找到时间实际释放渲染器到 loop();
。
否则 viewer.cleanup();
和 loop()
将被连续调用,中间没有时间发生任何其他事情。
注意:我没有做任何测试来确认
还有一个建议:也许你应该将你的 THREE.WebGLRenderer
实例放入一个单例中并重用它而不是释放它。
关于javascript - THREE.js webGL 垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20936692/