在场景中添加删除THREE.Geometry时,Three.JS VRAM内存泄漏

如何解决在场景中添加删除THREE.Geometry时,Three.JS VRAM内存泄漏

我的应用程序遇到VRAM内存泄漏。 该应用程序经常添加删除THREE.Geometry来创建体积动画。 如果我使用THREE.Geometry而不是拥有自己填充的顶点的THREE.SphereBufferGeometry,那么不会发生内存泄漏。

我创建了一个最小的应用程序来证明此内存泄漏是真实的。 内存泄漏会非常缓慢地增加VRAM内存,但最终会填满。 我认为池将无济于事,因为它是VRAM而不是托管内存。 我确实使用dispose。

如果您可以使此示例正常工作并且没有内存泄漏,则可能可以解决我的问题:

https://jsfiddle.net/4a7ksryd/16/

编辑:我在这里添加应用程序代码

var camera,scene,renderer;
var geometry,material,mesh;
var lastSphere;
var lastGeo;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70,window.innerWidth / window.innerHeight,0.01,10 );
    camera.position.z = 1;

    scene = new THREE.Scene();


    renderer = new THREE.Webglrenderer( { antialias: true } );
    renderer.setSize( window.innerWidth,window.innerHeight );
    renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap

    var light = new THREE.DirectionalLight( 0xffffff,1,100 );
light.position.set( 0,4,0 );          //default; light shining from top
light.castShadow = true;            // default false
//Set up shadow properties for the light
light.shadow.mapSize.width = 1024;  // default
light.shadow.mapSize.height = 1024; // default
light.shadow.camera.near = 1;    // default
light.shadow.camera.far = 20;     // default

scene.add( light );


    //Create a sphere that cast shadows (but does not receive them)

geometry = new THREE.SphereBufferGeometry( 0.1,32,32 );
material = new THREE.MeshStandardMaterial( { color: 0xff0000 } );
//    geometry = new THREE.BoxGeometry( 0.2,0.2,0.2 );
//    material = new THREE.MeshnormalMaterial();

    mesh = new THREE.Mesh( geometry,material );
    mesh.position.y = 0.1;
    mesh.castShadows = true;
    mesh.receiveShadow = false;
    scene.add( mesh );

    var planeGeometry = new THREE.PlaneBufferGeometry( 15,15,1 );
var planeMaterial = new THREE.MeshStandardMaterial( { color: 0xffffff,emissive:0x111111 } )
var plane = new THREE.Mesh( planeGeometry,planeMaterial );
plane.position.y = -0.2;
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add( plane );


    document.body.appendChild( renderer.domElement );

}

function animate() {

    requestAnimationFrame( animate );

    mesh.rotation.x += 0.01;
    mesh.rotation.y += 0.02;

        var dim = 32;
        var geo1 = new THREE.Geometry();
    const numVertices = dim*dim;
    var vertices = new Array(numVertices);
    for (var i=0; i<vertices.length; i++)
    {
        const x = i%dim;
        const y = (Math.floor(i/dim))%dim;    
      vertices[i] = new THREE.Vector3(x*0.1,y*0.1,0);
    }
    const numFaces = (dim-1)*(dim-1)*2;
    var faces = new Array(numFaces);

    for (var i=0; i<(faces.length/2); i++)
    {
        const x = i%(dim-1);
        const y = Math.floor(i/(dim-1))%(dim-1);
        faces[2*i] = new THREE.Face3(x+y*dim,x+1+y*dim,x+(y+1)*dim);
        faces[2*i+1] = new THREE.Face3(x+1+y*dim,x+1+(y+1)*dim,x+(y+1)*dim);
    }
    var uv = new Array(numFaces);
    for (var i=0; i<uv.length; i++)    
        uv[i] = [new THREE.Vector2(0,0),new THREE.Vector2(0,0)];
    geo1.faces = faces;
    geo1.vertices = vertices;
    geo1.faceVertexUvs[0] = uv;
        geo1.uvsNeedUpdate = true;
        geo1.verticesNeedUpdate = true;
        geo1.elementsNeedUpdate = true;
//    var sphereGeometry = new THREE.SphereBufferGeometry( 0.1,256,256 );
    var sphereGeometry = geo1;
    var sphereMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
    var sphere = new THREE.Mesh( sphereGeometry,sphereMaterial );
    sphere.position.y = 0.1+Math.sin(mesh.rotation.x)*0.1;
    sphere.position.x = 0.5;
    sphere.castShadow = true; //default is false
    sphere.receiveShadow = false; //default
    if (lastGeo!=null)
        lastGeo.dispose();
    if (lastSphere!=null)
        scene.remove(lastSphere);
    scene.add( sphere );
    lastSphere = sphere;
    lastGeo = sphereGeometry;
//    geo1.dispose();

    renderer.render( scene,camera );

}

解决方法

这实际上是three.js中的错误。我已提交公关以解决此问题:

https://github.com/mrdoob/three.js/pull/20479

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?