spite / THREE.MeshLine

Mesh replacement for THREE.Line
MIT License
2.18k stars 380 forks source link

Dashed lines disrupt transparent planes they're drawn over #131

Open lynn opened 3 years ago

lynn commented 3 years ago

Minimal example (jsfiddle):

<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
    <script src="https://unpkg.com/three.meshline@1.3.0/src/THREE.MeshLine.js"></script>
  </head>
  <body>
    <script>
      const container = document.createElement('div');
      document.body.appendChild(container);
      const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
      camera.position.set(0, 0, 150);
      const scene = new THREE.Scene();
      scene.add(camera);
      const renderer = new THREE.WebGLRenderer({ clearAlpha: 1 });
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setClearColor(0x101010, 1);
      document.body.appendChild(renderer.domElement);

      // A transparent red plane mesh at z=10:
      const plane = new THREE.Mesh(
        new THREE.PlaneGeometry(50, 50),
        new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.9 })
      );
      plane.position.set(0, 0, 10);
      plane.lookAt(camera.position);
      scene.add(plane);

      // A yellow dashed MeshLine that penetrates the plane:
      const line = new MeshLine();
      line.setPoints([-40,20,0,  40,0,20]);
      const lineMaterial = new MeshLineMaterial({ color: 0xffff00, transparent: true, dashArray: 0.05 });
      const mesh = new THREE.Mesh(line, lineMaterial);
      scene.add(mesh);

      // A blue dashed MeshLine fully in front of the plane:
      const line2 = new MeshLine();
      line2.setPoints([-40,0,20,  40,-20,20]);
      const line2Material = new MeshLineMaterial({ color: 0x0080ff, transparent: true, dashArray: 0.05 });
      scene.add(new THREE.Mesh(line2, line2Material));

      renderer.render(scene, camera);
      animate();
      function animate() {
        requestAnimationFrame(animate);
        mesh.material.uniforms.dashOffset.value -= 0.001
        renderer.render(scene, camera);
      }
    </script>
  </body>
</html>

This renders like so:

image

Another angle:

image

Note the black "gaps" that have appeared in the red plane.

If I remove transparent: true, opacity: 0.9 from the plane material, it renders correctly:

image