javascript - Three.js 中消失的线条对象

标签 javascript three.js



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

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

这是它在截屏视频中的样子:
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();
        }

最佳答案

问题是您正在绘制多个级别的不透明度,而 webgl 需要对它们进行排序。因此,简短的答案是将 depthTest: false 添加到您的立方体 Material 中。

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

但我想提一下,你所做的事情效率很低。你不应该这样绘制网格。请改用线条。

关于javascript - Three.js 中消失的线条对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33346970/

相关文章:

javascript - 所有图像的src与jquery

javascript - 如何计算 jQuery 表格中所选选项的特定值

javascript - 框架向下旋转

javascript - 使用 Three.js 将站点更改为连续动画

Three.js 将 Material 数组分配给索引的 BufferGeometry

javascript - jquery每个fadein输入框

javascript - 用于下载 pdf 文件的 Protractor e2e 测试用例

javascript - 如何使用HTML5 canvas和three.js实现4点透视变换?

javascript - Three.js:无法使用 THREE.ExtrudeGeometry 打洞(切割)线形状

javascript - 在 Instagram 中获取客户 ID 的评论权限