three.jsorthographic

objects behind objects with OrthographicCamera


I want a box to intersect with a polygon. It works fine with a PerspectiveCamera but when rendering with an OrthographicCamera the box is hidden behind the poly.

See my codesandbox here: https://codesandbox.io/s/gifted-bush-wbnlvy

You can simply change the boolean in line 23

var ortho = true; // <- change this

Perspective

enter image description here

Orthographic (red box should be visible as full square):

red box hidden behind poly with orthographic camera

And here is the relevant code

initializing the camera and scene


      var scene = new THREE.Scene();
    
      var ortho = true; // <- change this
    
      var camera = new THREE.OrthographicCamera(-5, 5, -5, 5);
      camera.position.set(0, 10, 0);
    
      if (!ortho) {
        camera = new THREE.PerspectiveCamera(
          45,
          window.innerWidth / window.innerHeight
        );
        camera.position.set(-4, 5, 4);
      }
    
      var renderer = new THREE.WebGLRenderer();
      renderer.setClearColor(new THREE.Color(0xffffff));
      renderer.setSize(window.innerWidth, window.innerHeight);
    
      // adding the two objects
      scene.add(
        createPoly([
          new Vector3(-2, 0, 2),
          new Vector3(2, 0, 2),
          new Vector3(1, 0, 0),
          new Vector3(2, 0, -2),
          new Vector3(-2, 0, -2)
        ])
      );
    
      scene.add(
        createBox(
          1, // size
          1, 0, 0 // pos
        )
      );
        
    
      function renderScene() {
        stats.update();
        trackballControls.update(clock.getDelta());
    
        window.requestAnimationFrame(renderScene);
        renderer.render(scene, camera); // render the scene
      }
    
      renderScene();

I build the objects with these functions


    function createPoly(points) {
    
      let polyShape = new Shape(
        points.map((v3) => {
          const v2 = new Vector2(v3.x, v3.z);
          return v2;
        })
      );
    
      const polyGeometry = new ShapeGeometry(polyShape);
    
      const polyMesh = new Mesh(
        polyGeometry,
        new MeshBasicMaterial({ color: 0x999999, side: DoubleSide })
      );
    
      // I have to rotate the poly as I am working in the x/z plane
      polyMesh.rotateX(Math.PI / 2);
    
      return polyMesh;
    }
    
    function createBox(size, posX, posY, posZ) {
      const geometry = new BoxGeometry(size, size, size);
    
      let material = new MeshBasicMaterial({
        color: 0xff00000
      });
    
      const box = new Mesh(geometry, material);
      box.position.set(posX, posY, posZ);
      return box;
    }
    

Solution

  • The OrthoCam docs say the constructor order is: left, right, top, bottom. You're initiating it with the top value lower than the bottom value:

    new THREE.OrthographicCamera(-5, 5, -5, 5);
    

    Having the top lower than the bottom is probably making your normals go haywire and thinking faces looking forward are inverted. Make sure top is higher than bottom.

    Fix:

    new THREE.OrthographicCamera(-5, 5, 5, -5);
    

    Result:

    enter image description here