在Three.js中消失的线对象

时间:2015-10-26 13:27:31

标签: javascript three.js



我有一个奇怪的问题,可能是一个three.js错误,但它也可以是我的曲线手。

我有一个带有一些网格的场景(例如下面我使用了几个透明的立方体和小球体)和一个线对象(可以是Line或LineSegments - 并不重要)基于缓冲几何。当我旋转相机线对象时,有时会从视图中消失,就像被另一个对象覆盖一样。如果我看不到起始点(如果将相机旋转到开始点在屏幕外的程度,即使没有额外的网格),而且线条对象的90%应该在视图中,它似乎也会消失。
<登记/> 问题是:为什么线条会消失,我应该如何防止这种行为?

这就是它在截屏视频中的表现:
http://screencast.com/t/HLC99OMmDdK

这就是问题的一个例子:
http://jsfiddle.net/exiara/sa4bxhc3/
你应该能够看到相机旋转时线条是如何消失的。

jsfiddle的代码示例:

        var camera, controls, scene, renderer, dummy, projector,
            stats, fps = 30, fpsTimeout = 1000 / fps,
            linesGeometry,globalLine;

        init();
        animate();

        function init() {

            renderer = new THREE.WebGLRenderer({antialias: true});
            renderer.setClearColor(0xFFFFeF, 1);
            renderer.setSize( window.innerWidth, window.innerHeight );
            document.body.appendChild( renderer.domElement );

            scene = new THREE.Scene();

            scene.fog = new THREE.Fog( 0xFFFFeF, 100, 2500 );

            camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 50000 );
            camera.position.set(-450, 300, 650);
            camera.target = new THREE.Vector3(0,0,0);
            controls = new THREE.OrbitControls( camera );
            controls.addEventListener('change', render );

            // ------------ MAIN PART START ------------ //

            var lines = 1000;
            linesGeometry = new THREE.BufferGeometry();
            var positions = new Float32Array( lines * 6 );
            for ( var i = 0, j, ll = lines; i < ll; i++ ) {
                j=i*6;
                positions[j]   = Math.random()*100;
                positions[j+1] = Math.random()*100;
                positions[j+2] = Math.random()*100;
                positions[j+3] = Math.random()*100;
                positions[j+4] = Math.random()*100;
                positions[j+5] = Math.random()*100;
            }
            linesGeometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
            globalLine = new THREE.Line( linesGeometry, new THREE.LineBasicMaterial({
                color: 0x000000,
                transparent: true,
                opacity: 0.8
            } ));
            scene.add( globalLine );

            // ------------ MAIN PART END ------------ //

            // add cubes
            var step = 400;
            var gridSize = 4;
            var offset = step*gridSize/2;

            var cubeGeometry = new THREE.BoxGeometry(step, step, step);
            var cubeMaterial = new THREE.MeshBasicMaterial({ color:0xFF0000, ambient: 0xCCCCCC, transparent: true, opacity: 0 });

            var testCube, edge;
            for (var x = -offset; x <= offset; x+=step) {
                for (var y = -offset; y <= offset; y+=step) {
                    for (var z = -offset; z <= offset; z+=step) {
                        testCube = new THREE.Mesh(cubeGeometry,cubeMaterial);
                        testCube.position.set(x, y, z);
                        edge = new THREE.EdgesHelper( testCube, 0x000000 );
                        scene.add(testCube);
                        scene.add(edge);
                    }
                }
            }

            // spheres
            var sphereGeometry = new THREE.SphereGeometry( 10,32,16),
                sphere;
            var spheres = [
                [0xff0000, 0,    0,    0   ], // red
                [0x0000ff, 200,  0,    0   ], // blue
                [0x00FF00, -200, 0,    0   ], // green
                [0xFF00ff, 0,    200,  0   ], // magenta
                [0x00ffff, 0,    -200, 0   ], // aqua
                [0xFFff00, 0,    0,    200 ], // lime
                [0x000000, 0,    0,    -200]  // black
            ];
            for (var i = 0, sl = spheres.length; i <sl; i++) {
                sphere = new THREE.Mesh(sphereGeometry, new THREE.MeshBasicMaterial({color: spheres[i][0]}));
                sphere.position.set(spheres[i][1], spheres[i][2], spheres[i][3]);
                scene.add(sphere);
            }

            /* Stats */
            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            document.body.appendChild( stats.domElement );

            /* window observers */
            window.addEventListener( 'resize', onWindowResize, false );
            window.addEventListener( 'load', render, false );
        }

        function onWindowResize() {

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

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

        function degInRad(deg) {
            return deg * Math.PI / 180;
        }

        function animate()
        {
            setTimeout(function() {
                requestAnimationFrame(animate);
            }, fpsTimeout );
            render();
        }

        function render() {
            camera.lookAt(camera.target);
            renderer.render( scene, camera );

            stats.update();
        }

1 个答案:

答案 0 :(得分:2)

问题是你在彼此之上绘制了多个级别的不透明度,而webgl需要对它们进行排序。所以简短的回答是将depthTest: false添加到您的多维数据集素材中。

var cubeMaterial = new THREE.MeshBasicMaterial({ color:0xFF0000, ambient: 0xCCCCCC, transparent: true, opacity: 0, depthTest: false });

但我想提一下你正在做的事情效率低下。你不应该以这种方式绘制网格。改为使用线条。