【问题标题】:How to make visible edges that are intersects other objects' surfaces?(THREE.js)如何使与其他对象表面相交的可见边缘?(三.js)
【发布时间】:2018-10-30 22:34:57
【问题描述】:

我在一个three.js 项目中工作。在项目中,我必须显示几何的所有边缘,即使这些边缘与其他对象的表面相交。

这是说明我的问题的 sn-p 代码。

var camera, scene, renderer, material, stats, group, wireframeMaterial;
init();
animate();

function init() {
    // Renderer.
    renderer = new THREE.WebGLRenderer({antialias: true, alpha:true,clearAlpha:0,clearColor: 0xff0000});
    //renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    // Add renderer to page
    document.body.appendChild(renderer.domElement);

    // Create camera.
    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.z = 400;

    // Create scene.
    scene = new THREE.Scene();
		group=new THREE.Group()

    // Create material
    material = new THREE.MeshBasicMaterial();

		wireframeMaterial=new THREE.LineBasicMaterial( { color: 0x000000, side:THREE.FrontSide ,transparent:false,opacity:1,linewidth: 1 })

    // Create cube and add to scene.
    var geometry = new THREE.BoxGeometry(200, 200, 200);
    var mesh1 = new THREE.Mesh(geometry, material);
    group.add(mesh1);
    
        
    var geometry2 = new THREE.BoxGeometry(100,100,100);
    var mesh2 = new THREE.Mesh(geometry2, material);
    group.add(mesh2);
    mesh2.position.fromArray([0,150,0])

    
    
    var edges = new THREE.EdgesGeometry( geometry );
    var line = new THREE.LineSegments( edges, wireframeMaterial );
    mesh1.add( line );


    var edges2 = new THREE.EdgesGeometry( geometry2 );
    var line2 = new THREE.LineSegments( edges2, wireframeMaterial );
    mesh2.add( line2 );


   		scene.add(group)

    // Add listener for window resize.
    window.addEventListener('resize', onWindowResize, false);
}

function animate() {
    requestAnimationFrame(animate);
    group.rotation.x += 0.005;
    group.rotation.y += 0.01; 
    renderer.render(scene, camera);
}

function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
}
body {
    padding: 0;
    margin: 0;
}
canvas {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js"></script>

在小提琴代码中,您可以看到两个立方体相互重叠。我希望小立方体的底部边缘变得可见。一种解决方案是使网格基础材料透明。然而,在这种情况下,立方体后面的边缘也将是可见的,这在项目中是不允许的。

那么对于这个问题还有其他的解决方案吗?

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    找到了很好的解决方案,需要用到基础材质的polygonOffset参数。

    var material = new THREE.MeshBasicMaterial({
      polygonOffset: true,
      polygonOffsetFactor: 1, // positive value pushes polygon further away
      polygonOffsetUnits: 1
    });
    

    在这个问题上找到它:three.js EdgesHelper showing certain diagonal lines on Collada model

    EdgesGeometry 将只渲染硬边。

    WireframeGeometry 将渲染所有边缘。

    var camera, scene, renderer, material, stats, group, wireframeMaterial;
    init();
    animate();
    
    function init() {
        // Renderer.
        renderer = new THREE.WebGLRenderer({antialias: true, alpha:true,clearAlpha:0,clearColor: 0xff0000});
        //renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        // Add renderer to page
        document.body.appendChild(renderer.domElement);
    
        // Create camera.
        camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
        camera.position.z = 400;
    
        // Create scene.
        scene = new THREE.Scene();
        group=new THREE.Group()
    
        // Create materials
        var material = new THREE.MeshBasicMaterial({
          polygonOffset: true,
          polygonOffsetFactor: 1, // positive value pushes polygon further away
          polygonOffsetUnits: 1
        });
        var wireframeMaterial= new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 2 } );
    
        // Create cube and add to scene.
        var geometry = new THREE.BoxGeometry(200, 200, 200);
        var edges = new THREE.EdgesGeometry(geometry);
        var line = new THREE.LineSegments( edges, wireframeMaterial );
        var mesh = new THREE.Mesh(geometry, material);
        group.add(mesh, line);
        
         
        var geometry2 = new THREE.BoxGeometry(100,100,100);
        var wire = new THREE.EdgesGeometry(geometry2);
        var line2 = new THREE.LineSegments( wire, wireframeMaterial );
        var mesh2 = new THREE.Mesh(geometry2, material);
        line2.position.fromArray([0,150,0]);
        mesh2.position.fromArray([0,150,0]);
        group.add(mesh2, line2);
        
    		scene.add(group)
    
        // Add listener for window resize.
        window.addEventListener('resize', onWindowResize, false);
    
        // Add stats to page.
        stats = new Stats();
        document.body.appendChild( stats.dom );
    }
    
    function animate() {
        requestAnimationFrame(animate);
        group.rotation.x += 0.005;
        group.rotation.y += 0.01; 
        renderer.render(scene, camera);
        stats.update();
    }
    
    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    }
    <script type="text/javascript" src="https://rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
    <script type="text/javascript" src="https://cdn.rawgit.com/mrdoob/stats.js/r17/build/stats.min.js"></script>

    【讨论】:

    • 我知道。但我不明白这与我的问题有什么关系。我只想显示硬边。问题是当线条与其他物体的表面相交时,它们就会消失。我想防止这种情况发生。
    • 现在我发现代码有问题。这是我脚本的早期版本。我已经更新了它。现在你可以更清楚地理解我的问题了。
    • 我将小盒子从大盒子移开一个单位,然后出现了线条。如果你可以在你的项目中做到这一点,那么它就解决了。如果您不能使用(或不想)请告诉我,以便我研究更好的解决方案。
    • 对不起,我不允许这样做:(
    • 谢谢。这是一个完美的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2020-04-02
    • 1970-01-01
    相关资源
    最近更新 更多