Hide a part of an object using masks (EffectComposer)
<h1>Description of the problem</h1>
<p>I am currently discovering the <code>EffectComposer</code> of <a href="http://threejs.org" rel="nofollow noreferrer">three.js</a> and I am looking for the method to hide a part of an object by another using masks.</p>
<p>Supposing you have a simple scene : a cube between the camera and a cylinder. The cube will have the role of the mask and hide the cylinder behind it :</p>
<p><a href="https://i.stack.imgur.com/X6fzn.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/X6fzn.jpg" alt="Cube hiding the cylinder behind it" /></a></p>
<h1>Solutions tested</h1>
<p>I have played with the following examples of ThreeJS and tried to tweak them to get the result I want, but without success :</p>
<ul>
<li><a href="https://threejs.org/examples/webgl_postprocessing.html" rel="nofollow noreferrer">https://threejs.org/examples/webgl_postprocessing.html</a></li>
<li><a href="https://threejs.org/examples/webgl_postprocessing_advanced.html" rel="nofollow noreferrer">https://threejs.org/examples/webgl_postprocessing_advanced.html</a></li>
</ul>
<p>The problem comes from the use of the passes I guess.</p>
<p>I tried two solutions (check the snippet below to know the type of the passes added) :</p>
<p><strong>1-</strong> Add the maskPass and then the renderPass so that the render of my scene will be drawn only inside my mask</p>
<pre><code>  composer = new THREE.EffectComposer(renderer, renderTarget);
  composer.addPass(maskPass1);
  composer.addPass(renderPass);
  composer.addPass(clearMaskPass);
  composer.addPass(outputPass);
</code></pre>
<p><strong>2-</strong> Add the renderPass, then the inverted mask, and a clearPass to remove the pixels</p>
<pre><code>  maskPass1.inverse = true;
  composer = new THREE.EffectComposer(renderer, renderTarget);
  composer.addPass(renderPass);
  composer.addPass(maskPass1);
  composer.addPass(clearPass);
  composer.addPass(clearMaskPass);
  composer.addPass(outputPass);
</code></pre>
<p>Below, you will find a code snippet showing what I've done until now. I used a <code>DotScreenPass</code> just to see the effect of the maskPass.</p>
<p>On the image below, you'll see the result I get using the snippet on the left side and the result I want on the right side</p>
<p><a href="https://i.stack.imgur.com/pXXGi.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/pXXGi.jpg" alt="Mask" /></a></p>
<h1>Code snippet</h1>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>var composer, renderer;
var box, torus;

init();
animate();

function init() {

  // Setup renderer
  renderer = new THREE.WebGLRenderer({antialias: false});
  renderer.setClearColor(0xe0e0e0);
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.autoClear = false;
  document.body.appendChild(renderer.domElement);

  // Setup scenes
  var camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000);
  camera.position.z = 10;

  var scene1 = new THREE.Scene();
  var scene2 = new THREE.Scene();

  // Add objects
  box = new THREE.Mesh(new THREE.BoxGeometry(4, 4, 4));
  box.rotateY(Math.PI / 6);
  box.rotateX(-Math.PI / 6);
  scene1.add(box);

  torus = new THREE.Mesh(new THREE.TorusGeometry(3, 1, 16, 32), new THREE.MeshBasicMaterial({
    color: 0xff0000
  }));
  scene2.add(torus);

  // Create passes for composer
  var clearPass = new THREE.ClearPass();
  var clearMaskPass = new THREE.ClearMaskPass();

  var maskPass1 = new THREE.MaskPass(scene1, camera);
  var maskPass2 = new THREE.MaskPass(scene2, camera);
  maskPass1.inverse = true
  var renderPass = new THREE.RenderPass(scene2, camera);

  var screenDotPass = new THREE.DotScreenPass();

  var outputPass = new THREE.ShaderPass(THREE.CopyShader);
  outputPass.renderToScreen = true;

  var renderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, {
    minFilter: THREE.LinearFilter,
    magFilter: THREE.LinearFilter,
    format: THREE.RGBFormat,
    stencilBuffer: true
  });

  // Create composer and add passes
  composer = new THREE.EffectComposer(renderer, renderTarget);
  composer.addPass(renderPass);
  composer.addPass(maskPass1);
  composer.addPass(screenDotPass);
  composer.addPass(clearMaskPass);
  composer.addPass(outputPass);

}

function animate() {

  requestAnimationFrame(animate);

  var time = performance.now() * 0.001;
  renderer.clear();
  composer.render(time);

}</code></pre>
<pre class="snippet-code-css lang-css prettyprint-override"><code>body
{
  background-color: #000;
  margin: 0px;
  overflow: hidden;
}</code></pre>
<pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div id="container"&gt;&lt;/div&gt;

&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/build/three.js"&gt;&lt;/script&gt;

&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/shaders/CopyShader.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/shaders/DotScreenShader.js"&gt;&lt;/script&gt;

&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/postprocessing/EffectComposer.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/postprocessing/ClearPass.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/postprocessing/TexturePass.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/postprocessing/ShaderPass.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/postprocessing/MaskPass.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/postprocessing/DotScreenPass.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/postprocessing/RenderPass.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/postprocessing/DotScreenPass.js"&gt;&lt;/script&gt;

&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/Detector.js"&gt;&lt;/script&gt;
&lt;script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/libs/stats.min.js"&gt;&lt;/script&gt;</code></pre>
</div>
</div>
</p>