使用A帧显示立体图像的GL_OUT_OF_Memory [英] GL_OUT_OF_MEMORY using A-frame to display stereoscopic images
本文介绍了使用A帧显示立体图像的GL_OUT_OF_Memory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我已经创建了一个概念验证SPA(source code/demo),它从Web服务器加载立体图像,并使用A-frame的aframe-stereo-component以立体3D形式呈现它们。
在Oculus浏览器和Firefox Reality的Quest 2上进行了测试,效果很好:通过WebXR以沉浸式VR模式查看时,每个图像都以3D形式显示。
但是,在滚动浏览多个图像(通常为8到12个)后,幻灯片放映将停止工作。 在Firefox的现实中,这一点体现在应用程序只是冻结和变得没有反应。在Oculus浏览器中,显示图像描述,但图像区域保持黑色。 将Quest 2连接到安装了ADB的PC上,并使用Chrome DevTools查看页面,出现这种情况时,我可以看到以下输出:
23:07:59.195 [.WebGL-0x55930300]GL ERROR :GL_OUT_OF_MEMORY : glTexImage2D:
23:07:59.195 [.WebGL-0x55930300]GL ERROR :GL_INVALID_OPERATION : glGenerateMipmap: Can not generate mips
23:07:59.195 [.WebGL-0x55930300]RENDER WARNING: texture bound to texture unit 0 is not renderable. It might be non-power-of-2 or have incompatible texture filtering (maybe)?
23:08:03.340 [.WebGL-0x55930300]GL ERROR :GL_OUT_OF_MEMORY : glTexImage2D:
23:08:03.340 [.WebGL-0x55930300]GL ERROR :GL_INVALID_OPERATION : glGenerateMipmap: Can not generate mips
23:08:03.340 [.WebGL-0x55930300]GL ERROR :GL_OUT_OF_MEMORY : glTexImage2D:
23:08:03.340 [.WebGL-0x55930300]GL ERROR :GL_INVALID_OPERATION : glGenerateMipmap: Can not generate mips
23:08:03.499 WebGL: too many errors, no more errors will be reported to the console for this context.
诚然,加载的图像是大型JPS文件(2到3MB),每个图像渲染两次:一只眼睛一次。
但是,<img>
元素用于通过将图像内容添加到DOM来加载图像内容,当请求下一个图像时,该元素将被移除并设置为空以使图像内容无效,因此理论上一次只应加载一个图像。
因此,我假设一定是某个地方的内存泄漏,导致加载了大量图像后内存被填满,但我不确定它是在哪里泄漏的。
我无法在使用Chrome/Firefox的PC上重现这个问题,但这可能是因为它的内存比Quest 2更大。
相关source code摘录:
<a-scene id="scene" vr-mode-ui="enabled: false" >
<a-assets id="assets"></a-assets>
<a-plane id="left-image"
material="repeat:0.5 1"
scale="2 1 1"
position="0 0 -1"
stereo="eye:left"
>
</a-plane>
<a-plane id="right-image"
material="repeat:0.5 1; offset: 0.5 0"
scale="2 1 1"
position="0 0 -1"
stereo="eye: right"
></a-plane>
</a-scene>
const stereoImageId = 'fullsize-image'
const _stereoImage = '#'+stereoImageId;
const leye = $('#left-image')[0];
const reye = $('#right-image')[0];
const $assets = $('#assets');
const removeStereoImage = function(){
let $stereoImage = $(_stereoImage);
if($stereoImage.length){
let stereoImage = $stereoImage[0];
stereoImage.onload = stereoImage.onerror = null;
$stereoImage.attr('src', '').remove();
$stereoImage = stereoImage = null;
}
};
const unloadStereoImage = function(){
removeStereoImage();
leye.setAttribute("material", "src", '');
reye.setAttribute("material", "src", '');
setStereoImageVisibility(false);
};
const setStereoImageVisibility = function(visible){
leye.setAttribute("visible", visible)
reye.setAttribute("visible", visible)
};
const showImg = function(url, description){
function onImgLoaded(){
leye.setAttribute("material", "src", _stereoImage);
reye.setAttribute("material", "src", _stereoImage);
setStereoImageVisibility(true);
}
unloadStereoImage();
let stereoImage = document.createElement('img');
stereoImage.setAttribute('id', stereoImageId);
stereoImage.setAttribute('crossorigin', "anonymous");
stereoImage.setAttribute('src', url);
stereoImage.onload = onImgLoaded;
$(stereoImage).appendTo($assets);
};
我还在源代码repo中raised this as an issue
推荐答案
资产管理系统(a-assets
)旨在帮助管理preloading资产,而不是在运行时将它们抛入抛出。
从资产中删除<img>
元素不会释放纹理(它缓存在material system中)。
您可以访问和清除缓存,但我会尝试‘手动’管理图像,
通过
加载图像new THREE.Texture(src)
像material system does使用
应用材料element.getObject3D("mesh").material.map = texture; material.needsUpdate = true;
- 删除旧纹理
我以为纹理too big,但我猜每个纹理都会崩溃。
这篇关于使用A帧显示立体图像的GL_OUT_OF_Memory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文