【问题标题】:Display loaded OBJ model in wireframe mode in three.js在three.js中以线框模式显示加载的OBJ模型
【发布时间】:2020-08-02 17:59:05
【问题描述】:

我想以线框模式显示我加载的 .obj 文件.. 我了解了 WireFrameGeometry 但由于某种原因,.mtl 纹理只能显示。

下面是代码..

  /* Model */

 var mtlLoader = new THREE.MTLLoader();
 mtlLoader.setBaseUrl('assets/');
 mtlLoader.setPath('assets/');
 mtlLoader.load('materialfile.mtl', function(materials) {

     materials.preload();


     var objLoader = new THREE.OBJLoader();
     objLoader.setMaterials(materials);
     objLoader.setPath('assets/');
     objLoader.load('Objectfile.obj', function(object) {

         object.traverse(function(child) {

             if (child.isMesh) {

                 var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
                 var wireframeMaterial = new THREE.LineBasicMaterial({
                     color: 0xffffff
                 });
                 var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
                 child.add(wireframe);

             }
         });
         scene.add(object);

     });

 });

我只想要模型的线框没有任何填充..

提前致谢。

整个代码如下...


<!DOCTYPE html>
<html>

<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <script src="three.js"></script>
    <script src="TrackballControls.js"></script>
    <script src="cannon.js"></script>
    <script src="Detector.js"></script>
    <script src="OrbitControls.js"></script>
    <script src="OBJLoader.js"></script>
    <script src="MTLLoader.js"></script>


</head>

<body>

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

        var container;

        var camera, controls, scene, renderer;
        var lighting, ambient, keyLight, fillLight, backLight;

        init();
        animate();

        function init() {

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

            /* Camera */

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


            /* Scene */

            scene = new THREE.Scene();
            lighting = false;

            ambient = new THREE.AmbientLight(0xffffff, 1.0);
            scene.add(ambient);

            // keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
            // keyLight.position.set(-100, 0, 100);

            // fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
            // fillLight.position.set(100, 0, 100);

            // backLight = new THREE.DirectionalLight(0xffffff, 1.0);
            // backLight.position.set(100, 0, -100).normalize();

            /* Model */

            // var mtlLoader = new THREE.MTLLoader();
            // mtlLoader.setBaseUrl('assets/');
            // mtlLoader.setPath('assets/');
            // mtlLoader.load('mtlfile.mtl', function(materials) {

            //     materials.preload();

            // materials.materials.default.map.magFilter = THREE.NearestFilter;
            // materials.materials.default.map.minFilter = THREE.LinearFilter;

            var objLoader = new THREE.OBJLoader();
            // objLoader.setMaterials(materials);
            objLoader.setPath('assets/');
            objLoader.load('objectfile.obj', function(object) {

                object.traverse(function(child) {

                    if (child.isMesh) {

                        var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
                        var wireframeMaterial = new THREE.LineBasicMaterial({
                            color: 0xeeeeee
                        });
                        var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);

                        // add to child so we get same orientation
                        child.add(wireframe);
                        // to parent of child. Using attach keeps our orietation
                        child.parent.attach(wireframe);
                        // remove child (we don't want child)
                        child.parent.remove(child);

                    }
                });
                scene.add(object);

            });

            // });

            /* Renderer */

            renderer = new THREE.WebGLRenderer();
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setClearColor(new THREE.Color("hsl(0, 0%, 10%)"));

            container.appendChild(renderer.domElement);

            /* Controls */

            controls = new THREE.OrbitControls(camera, renderer.domElement);
            controls.enableDamping = true;
            controls.dampingFactor = 0.25;
            controls.enableZoom = true;
            controls.autoRotate = true;


            /* Events */

            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();

            render();

        }

        function render() {

            renderer.render(scene, camera);

        }
    </script>

</body>

</html>



所以这是整个代码.. 它只是基本的 obj 加载器.. 我不知道问题出在代码还是模型中。 它显示为一个完全填充的白色模型

【问题讨论】:

    标签: three.js 3d-model wireframe


    【解决方案1】:
    
             object.traverse(function(child) {
    
                 if (child.isMesh) {
    
                    child.material.wireframe = true;
    
                 }
             }
    

    【讨论】:

    • ///仍然没有出现在线框中,它只是显示带有 mtl 纹理的模型////var objLoader = new THREE.OBJLoader(); objLoader.setMaterials(材料); objLoader.setPath('assets/'); objLoader.load('objectfile.obj', function(object) { object.traverse(function(child) { if (child.isMesh) { child.material.wireframe = true; } }); scene.add(object); });
    • 如果你不想要有纹理的线条,你必须设置 child.material.map = null
    【解决方案2】:

    这对我有用

     objLoader.load('Objectfile.obj', function(object) {
    
         object.traverse(function(child) {
    
             if (child.isMesh) {
    
                 var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
                 var wireframeMaterial = new THREE.LineBasicMaterial({
                     color: 0xffffff
                 });
                 var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
    
                 // add to child so we get same orientation
                 child.add(wireframe);
                 // to parent of child. Using attach keeps our orietation
                 child.parent.attach(wireframe);
                 // remove child (we don't want child)
                 child.parent.remove(child);
    
             }
         });
         scene.add(object);
    
     });
    

    例子:

    html, body {
      margin: 0;
      height: 100%;
    }
    #c {
      width: 100%;
      height: 100%;
      display: block;
    }
    <canvas id="c"></canvas>
    <script type="module">
    import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
    import {OrbitControls} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/controls/OrbitControls.js';
    import {OBJLoader2} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/OBJLoader2.js';
    
    function main() {
      const canvas = document.querySelector('#c');
      const renderer = new THREE.WebGLRenderer({canvas});
    
      const fov = 45;
      const aspect = 2;  // the canvas default
      const near = 0.1;
      const far = 100;
      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
      camera.position.set(0, 10, 20);
    
      const controls = new OrbitControls(camera, canvas);
      controls.target.set(0, 5, 0);
      controls.update();
    
      const scene = new THREE.Scene();
      scene.background = new THREE.Color('black');
    
      {
        const objLoader = new OBJLoader2();
        objLoader.load('https://threejsfundamentals.org/threejs/resources/models/windmill/windmill.obj', (root) => {
          root.traverse(child => {
                 if (child.isMesh) {
    
                     var wireframeGeomtry = new THREE.WireframeGeometry(child.geometry);
                     var wireframeMaterial = new THREE.LineBasicMaterial({
                         color: 0xffffff
                     });
                     var wireframe = new THREE.LineSegments(wireframeGeomtry, wireframeMaterial);
                     child.add(wireframe);
                     child.parent.attach(wireframe);
                     child.parent.remove(child);
                 }
          });
          scene.add(root);
        });
      }
    
      function resizeRendererToDisplaySize(renderer) {
        const canvas = renderer.domElement;
        const width = canvas.clientWidth;
        const height = canvas.clientHeight;
        const needResize = canvas.width !== width || canvas.height !== height;
        if (needResize) {
          renderer.setSize(width, height, false);
        }
        return needResize;
      }
    
      function render() {
    
        if (resizeRendererToDisplaySize(renderer)) {
          const canvas = renderer.domElement;
          camera.aspect = canvas.clientWidth / canvas.clientHeight;
          camera.updateProjectionMatrix();
        }
    
        renderer.render(scene, camera);
    
        requestAnimationFrame(render);
      }
    
      requestAnimationFrame(render);
    }
    
    main();
    
    </script>

    您也可以按照 manthrax 建议的方式进行操作,除非您需要检查 child.material 是否为数组,然后为每种材质移除贴图(因此不使用纹理)并将 emissive 设置为某种颜色(您可能还想将color 设置为黑色)`。

    html, body {
      margin: 0;
      height: 100%;
    }
    #c {
      width: 100%;
      height: 100%;
      display: block;
    }
    <canvas id="c"></canvas>
    <script type="module">
    import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
    import {OrbitControls} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/controls/OrbitControls.js';
    import {OBJLoader2} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/OBJLoader2.js';
    
    function main() {
      const canvas = document.querySelector('#c');
      const renderer = new THREE.WebGLRenderer({canvas});
    
      const fov = 45;
      const aspect = 2;  // the canvas default
      const near = 0.1;
      const far = 100;
      const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
      camera.position.set(0, 10, 20);
    
      const controls = new OrbitControls(camera, canvas);
      controls.target.set(0, 5, 0);
      controls.update();
    
      const scene = new THREE.Scene();
      scene.background = new THREE.Color('black');
    
      function makeWireframe(material) {
        material.wireframe = true;
        material.emissive.set('#0FF');
        material.map = undefined;
      }
    
      {
        const objLoader = new OBJLoader2();
        objLoader.load('https://threejsfundamentals.org/threejs/resources/models/windmill/windmill.obj', (root) => {
          root.traverse(child => {
                 if (child.isMesh) {
                    if (Array.isArray(child.material)) {
                      child.material.forEach(makeWireframe);
                    } else {
                      makeWireframe(child.material)
                    }
                 }
          });
          scene.add(root);
        });
      }
    
      function resizeRendererToDisplaySize(renderer) {
        const canvas = renderer.domElement;
        const width = canvas.clientWidth;
        const height = canvas.clientHeight;
        const needResize = canvas.width !== width || canvas.height !== height;
        if (needResize) {
          renderer.setSize(width, height, false);
        }
        return needResize;
      }
    
      function render() {
    
        if (resizeRendererToDisplaySize(renderer)) {
          const canvas = renderer.domElement;
          camera.aspect = canvas.clientWidth / canvas.clientHeight;
          camera.updateProjectionMatrix();
        }
    
        renderer.render(scene, camera);
    
        requestAnimationFrame(render);
      }
    
      requestAnimationFrame(render);
    }
    
    main();
    
    </script>

    【讨论】:

    • 我还是看不到线框。我只能看到一个白色的网格.. :(
    • 那么也许您应该在snippet 中发布运行代码。我的答案中的 2 个 sn-ps 都在运行。
    • 我无法添加 sn-p 。但会在问题中添加整个代码
    猜你喜欢
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 2014-06-21
    • 2013-04-26
    • 1970-01-01
    • 2018-04-30
    • 2022-08-10
    • 2013-11-08
    相关资源
    最近更新 更多