Three.js threejs:与精灵/正交摄影机组合删除几何体或缓冲几何体时出错

Three.js threejs:与精灵/正交摄影机组合删除几何体或缓冲几何体时出错,three.js,Three.js,我在ThreeJSR69中使用ctm二进制加载程序加载了一些对象。这将在内部使用缓冲几何体返回网格对象。 我需要从场景中删除,然后删除其中一个网格,包括它们的材质/纹理/几何体。根据示例和谷歌,我应该使用: scene.remove(m_mesh); m_mesh.geometry.dispose(); m_mesh.geometry = null; m_mesh.material.dispose(); m_mesh.material = null; m_mesh = null; 这会将对象从

我在ThreeJSR69中使用ctm二进制加载程序加载了一些对象。这将在内部使用缓冲几何体返回网格对象。 我需要从场景中删除,然后删除其中一个网格,包括它们的材质/纹理/几何体。根据示例和谷歌,我应该使用:

scene.remove(m_mesh);
m_mesh.geometry.dispose();
m_mesh.geometry = null;
m_mesh.material.dispose();
m_mesh.material = null;
m_mesh = null;
这会将对象从场景中移除,但屏幕会变黑一秒钟,并且出现GL错误:

Error: WebGL: drawElements: no VBO bound to enabled vertex attrib index 2!
看起来上面的序列(在绘制场景之前在我的render()操作中运行)并没有清除所有内容,或者至少我仍然在某处引用了不存在的VBO

我花了相当长的时间调试这个问题,得出的结论是,只有在两个不同的场景中使用带有精灵和透视摄影机的正交摄影机时,才会发生这种情况

基本上,我使用精灵和专用场景绘制平面背景,然后使用网格绘制3D场景。如果从3D场景中删除网格,则平面背景的绘制将失败。 我不明白为什么。看起来删除精灵上的网格会产生副作用,即使附加到不同的场景。 如果我对背景图形进行注释,则删除网格的操作非常有效

我在下面插入一个使用标准threejs发行版的问题复制品。等待大约5秒钟,您应该会在jaavscript控制台上看到一些GL错误

<!DOCTYPE html>
<html lang="en">

<head>
    <title>three.js webgl - geometries</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            font-family: Monospace;
            background-color: #000;
            margin: 0px;
            overflow: hidden;
        }
    </style>
</head>

<body>

    <script src="build/three.min.js"></script>
    <script src="js/Detector.js"></script>
    <script src="js/libs/stats.min.js"></script>

    <script>
        if (!Detector.webgl) Detector.addGetWebGLMessage();

        var container, stats;

        var camera, scene, renderer;
        frame_count = 0;

        init();
        animate();

        function init() {

            container = document.createElement('div');
            document.body.appendChild(container);

            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
            camera.position.y = 400;

            // I need a second camera for my 2D sprite (used as a background)
            // must use another texture so that it's not destroyed when removing the first object
            cameraOrtho = new THREE.OrthographicCamera(window.innerWidth / -2,
                window.innerWidth / 2,
                window.innerHeight / 2,
                window.innerHeight / -2,
                1, 10);

            cameraOrtho.position.z = 10;
            cameraOrtho.position.y = 400;
            sceneBackground = new THREE.Scene();

            var map1 = THREE.ImageUtils.loadTexture('textures/disturb.jpg');
            var material1 = new THREE.SpriteMaterial({
                map: map1
            });
            var spriteBackground = new THREE.Sprite(material1);
            spriteBackground.scale.set(window.innerWidth, window.innerHeight, 1);

            spriteBackground.position.set(window.innerWidth / 2,
                window.innerHeight / 2);
            sceneBackground.add(spriteBackground);

            scene = new THREE.Scene();

            var light;
            my_object = null;

            scene.add(new THREE.AmbientLight(0x404040));

            light = new THREE.DirectionalLight(0xffffff);
            light.position.set(0, 1, 0);
            scene.add(light);

            var map = THREE.ImageUtils.loadTexture('textures/UV_Grid_Sm.jpg');
            map.wrapS = map.wrapT = THREE.RepeatWrapping;
            map.anisotropy = 16;

            var material = new THREE.MeshLambertMaterial({
                map: map,
                side: THREE.DoubleSide
            });

            // one object is enough to demonstrate

            // can't reproduce the problem with a standard SphereGeometry
            // try to convert it to a BufferGeometry
            var sphereGeometry = new THREE.SphereGeometry(75, 20, 10);
            var bufferGeometry = new THREE.BufferGeometry().fromGeometry(sphereGeometry);

            my_object = new THREE.Mesh(bufferGeometry, material);
            my_object.position.set(-400, 0, 200);
            scene.add(my_object);

            renderer = new THREE.WebGLRenderer({
                antialias: true
            });
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.autoClear = false;
            renderer.autoClearDepth = false;

            container.appendChild(renderer.domElement);

            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            container.appendChild(stats.domElement);

            window.addEventListener('resize', onWindowResize, false);
        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize(window.innerWidth, window.innerHeight);

        }

        //

        function animate() {

            requestAnimationFrame(animate);

            render();
            stats.update();

        }

        function render() {
            frame_count++;

            var timer = Date.now() * 0.0001;

            camera.position.x = Math.cos(timer) * 800;
            camera.position.z = Math.sin(timer) * 800;

            camera.lookAt(scene.position);


            //after a few frames I want to destroy completely the object
            //means remove from the scene, remove texture, material, geometry
            //note that here it's a Geometry, not a BufferGeometry
            //may be different

            if (frame_count > 60 * 5) {
                if (my_object != null) {

                    console.log("destroy object buffer");
                    scene.remove(my_object);
                    my_object.material.map.dispose();
                    my_object.material.dispose();
                    my_object.geometry.dispose();
                    my_object = null;
                }
            }

            for (var i = 0, l = scene.children.length; i < l; i++) {

                var object = scene.children[i];

                object.rotation.x = timer * 5;
                object.rotation.y = timer * 2.5;

            }

            renderer.render(sceneBackground, cameraOrtho);
            renderer.clearDepth();
            renderer.render(scene, camera);

        }
    </script>

</body>

</html>

three.js webgl-几何图形
身体{
字体系列:Monospace;
背景色:#000;
边际:0px;
溢出:隐藏;
}
如果(!Detector.webgl)Detector.addGetWebGLMessage();
var容器,stats;
摄像机、场景、渲染器;
帧计数=0;
init();
制作动画();
函数init(){
container=document.createElement('div');
文件.正文.附件(容器);
摄像头=新的三个透视摄像头(45,window.innerWidth/window.innerHeight,12000);
摄像机位置y=400;
//我需要第二台照相机来拍摄2D精灵(用作背景)
//必须使用另一个纹理,以便在移除第一个对象时不会破坏它
cameraOrtho=新的三个正交摄影机(window.innerWidth/-2,
window.innerWidth/2,
window.innerHeight/2,
window.innerHeight/-2,
1, 10);
摄像机正交位置z=10;
摄像机正交位置y=400;
sceneBackground=new THREE.Scene();
var map1=THREE.ImageUtils.loadTexture('textures/扰动.jpg');
var material1=新的三种精神材料({
地图:map1
});
变量spriteBackground=新的三个Sprite(材料1);
spriteBackground.scale.set(window.innerWidth,window.innerHeight,1);
spriteBackground.position.set(window.innerWidth/2,
窗内高度(1/2);
sceneBackground.add(spriteBackground);
场景=新的三个。场景();
var灯;
my_object=null;
添加(新的三个环境光(0x404040));
灯光=新的三个方向灯光(0xffffff);
光。位置。设置(0,1,0);
场景。添加(灯光);
var map=THREE.ImageUtils.loadTexture('textures/UV_Grid_Sm.jpg');
map.wrapps=map.wrapT=THREE.RepeatWrapping;
map.各向异性=16;
var material=新的3.0网格LambertMaterial({
地图:地图,
侧面:三个。双面
});
//一件物品足以证明
//无法用标准的球面测量法重现该问题
//尝试将其转换为缓冲几何体
var比色法=新的三种比色法(75,20,10);
var bufferGeometry=new THREE.bufferGeometry().fromGeometry(sphereGeometry);
my_object=新的三点网格(缓冲几何体、材质);
my_object.position.set(-400,0200);
添加(我的对象);
renderer=new THREE.WebGLRenderer({
反别名:对
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth、window.innerHeight);
renderer.autoClear=false;
renderer.autoClearDepth=false;
container.appendChild(renderer.domeElement);
统计数据=新统计数据();
stats.domElement.style.position='绝对';
stats.domElement.style.top='0px';
container.appendChild(stats.domeElement);
addEventListener('resize',onWindowResize,false);
}
函数onWindowResize(){
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectMatrix();
renderer.setSize(window.innerWidth、window.innerHeight);
}
//
函数animate(){
请求动画帧(动画);
render();
stats.update();
}
函数render(){
帧计数++;
var timer=Date.now()*0.0001;
camera.position.x=数学cos(计时器)*800;
camera.position.z=Math.sin(计时器)*800;
摄像机。注视(场景。位置);
//几帧之后,我想彻底摧毁这个物体
//表示从场景中移除、移除纹理、材质和几何体
//请注意,这里是一个几何体,而不是缓冲区几何体
//可能不同
如果(帧计数>60*5){
如果(我的对象!=null){
log(“销毁对象缓冲区”);
场景。移除(我的对象);
my_object.material.map.disp