Rhino 对象 Three.js 可视化问题

Rhino obj to Three.js visualisation problems

在测试 Rhino 和 Three 之间的 import/export 时,我在可视化一个相当复杂的 obj 文件时遇到了一些问题。在对网格进行三角剖分后,我从 Rhino 导出了对象。

问题在 material 中独立显示:没有 material,有 material or/and,在三中应用了纹理。

我尝试从 Rhino 导入的几何 Jpeg 与 Three.js 上的结果:http://goo.gl/1WMGSu

如您所见,存在一些奇怪的深度问题,尤其是取决于相机位置。 我对该主题进行了长时间的研究,但没有找到解决方案。我将在 Whosebug 上附加一些我已经关注的其他主题。

我自己也尝试在 Rhino 中检查和翻转法线,但没有成功。

我的脚本(更新了 Gaitat 建议):

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - loaders - OBJ loader</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;
                color: #fff;
                margin: 0px;
                overflow: hidden;
            }
            #info {
                color: #fff;
                position: absolute;
                top: 10px;
                width: 100%;
                text-align: center;
                z-index: 100;
                display:block;
            }
            #info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
        </style>
    </head>

    <body>
        <div id="info">
        <a href="http://threejs.org" target="_blank">three.js</a> - OBJLoader test
        </div>

        <script src="../build/three.min.js"></script>
        <script src="js/loaders/OBJLoader.js"></script>

        <script>

            var container;

            var camera, scene, renderer;

            var mouseX = 0, mouseY = 0;

            var windowHalfX = window.innerWidth / 2;
            var windowHalfY = window.innerHeight / 2;


            init();
            animate();


            function init() {

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

                camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 1, 2500 );
                camera.position.z = 50;

                // scene

                scene = new THREE.Scene();

                var ambient = new THREE.AmbientLight( 0x101030 );
                scene.add( ambient );

                var directionalLight = new THREE.DirectionalLight( 0xffeedd );
                directionalLight.position.set( 0, 0, 1 );
                scene.add( directionalLight );

                // texture

                var manager = new THREE.LoadingManager();
                manager.onProgress = function ( item, loaded, total ) {

                    console.log( item, loaded, total );

                };

                var texture = new THREE.Texture();

                var onProgress = function ( xhr ) {
                    if ( xhr.lengthComputable ) {
                        var percentComplete = xhr.loaded / xhr.total * 100;
                        console.log( Math.round(percentComplete, 2) + '% downloaded' );
                    }
                };

                var onError = function ( xhr ) {
                };


                var loader = new THREE.ImageLoader( manager );
                loader.load( 'textures/UV_Grid_Sm.jpg', function ( image ) {

                    texture.image = image;
                    texture.needsUpdate = true;

                } );

                // model

                loader = new THREE.OBJLoader( manager );
                loader.load( 'obj/RU_obj/testTriangulated_again.obj', function ( object ) {

                    object.traverse( function ( child ) {

                        if ( child instanceof THREE.Mesh ) {

                            child.material.map = texture;

                        }

                    } );

                    object.position.y = - 30;
                    object.scale.x = 0.5;
                    object.scale.y = 0.5;
                    object.scale.z = 0.5;

                    scene.add( object );

                }, onProgress, onError );

                //

                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                container.appendChild( renderer.domElement );

                document.addEventListener( 'mousemove', onDocumentMouseMove, false );

                //

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

            }

            function onWindowResize() {

                windowHalfX = window.innerWidth / 2;
                windowHalfY = window.innerHeight / 2;

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

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

            }

            function onDocumentMouseMove( event ) {

                mouseX = ( event.clientX - windowHalfX ) / 2;
                mouseY = ( event.clientY - windowHalfY ) / 2;

            }

            //

            function animate() {

                requestAnimationFrame( animate );
                render();

            }

            function render() {

                camera.position.x += ( mouseX - camera.position.x ) * .05;
                camera.position.y += ( - mouseY - camera.position.y ) * .05;
                camera.lookAt( scene.position );

                renderer.render( scene, camera );

            }

        </script>

    </body>
</html>

这是我的 obj 文件:http://goo.gl/hTD43D.

提前致谢。

替换此代码:

loader.load('obj/RU_obj/testTriangulated.obj', function(geometry) {
    var material =  new THREE.MeshPhongMaterial( { color: 0x00ff00 } );
    geometry.position.y = 0;
    geometry.material = material;
    scene.add(geometry);
});

var material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } );
loader.load('obj/RU_obj/testTriangulated.obj', function(object) {
    scene.add( new THREE.Mesh (object.geometry, material) );
});

您不能像以前那样分配 material。我正在做的是使用加载对象的几何形状并创建一个新网格,然后将其添加到场景中。

更新

您的物体实际上是从里到外的,所以您看到的是它的内部。所以在 Rhino 中,您必须更改法线或更改多边形的方向。此处的解决方法是使用双面 material。 此代码已修复:

<body>
    <div id="info">
    <a href="http://threejs.org" target="_blank">three.js</a> - OBJLoader test
    </div>

    <script src="../build/three.min.js"></script>
    <script src="js/loaders/OBJLoader.js"></script>
    <script src="js/controls/TrackballControls.js"></script>

    <script>

        var container;
        var camera, scene, renderer, controls;
        var mouseX = 0, mouseY = 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.z = 100;

            // scene

            scene = new THREE.Scene();

            // lights

            var ambient = new THREE.AmbientLight( 0x101030 );
            scene.add( ambient );

            var directionalLight = new THREE.DirectionalLight( 0xffeedd );
            directionalLight.position.set( 0, 0, 1 );
            scene.add( directionalLight );

            // texture

            var manager = new THREE.LoadingManager();
            manager.onProgress = function ( item, loaded, total ) { };

            var texture = new THREE.Texture();

            var loader = new THREE.ImageLoader( manager );
            loader.load( 'textures/UV_Grid_Sm.jpg', function ( image )
            {
                texture.image = image;
                texture.needsUpdate = true;
            } );

            // model

            var loader = new THREE.OBJLoader( manager );
            loader.load( 'testTriangulated.obj', function ( object )
            {
                object.traverse( function ( child )
                {
                    if ( child instanceof THREE.Mesh )
                    {
                        child.material.map = texture;
                        child.material.side = THREE.DoubleSide;
                    }
                } );

                scene.add( object );
            } );

            //

            renderer = new THREE.WebGLRenderer();
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );

            // controls
            controls = new THREE.TrackballControls (camera, renderer.domElement);
            controls.rotateSpeed = 1.0;
            controls.zoomSpeed = 1.2;

            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 );
            controls.update();
            renderer.render( scene, camera );
        }

    </script>

</body>