如何使与其他对象的表面相交的可见边缘?(THREE.js)

时间:2018-10-25 12:55:06

标签: javascript three.js

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

这是说明我的问题的代码段。

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>

在小提琴代码中,您可以看到彼此之间有两个立方体。我希望小立方体的底部边缘变得可见。一种解决方案是使网状基础材料透明。但是,在这种情况下,位于立方体后面的边缘本身也将可见,这在项目中是不允许的。

那么这个问题有其他解决方案吗?

1 个答案:

答案 0 :(得分: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>