three.js post processing maskpass with multiple renderpass never works

this never works:

composer.addPass( clearPass );
composer.addPass( renderPass0 );
composer.addPass( maskPass );
composer.addPass( renderPass1 );
composer.addPass( clearMaskPass );
composer.addPass( outputPass );

if i switch out “renderPass1” with a “texturePass” it works.

Anyone able to compose two renderPasses?

Posting the chain of your passes is probably not enough information to solve the problem. Please try to provide a live example so it’s possible to debug your demo.

Crossposting:

Thank you! I am currently working to create a pastebin for more detail.

I am working towards this:

postprocessing renderPass_1, maskPass, renderPass_2, desired result

Here is the code:

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				background-color: #000;
				margin: 0px;
				overflow: hidden;
			}
		</style>
	</head>
	<body>
		<div id="container"></div>
		<script src="../build/three.js"></script>
		<script src="js/shaders/CopyShader.js"></script>
		<script src="js/postprocessing/EffectComposer.js"></script>
		<script src="js/postprocessing/ClearPass.js"></script>
		<script src="js/postprocessing/ShaderPass.js"></script>
		<script src="js/postprocessing/MaskPass.js"></script>
		<script src="js/postprocessing/RenderPass.js"></script>
		<script src="js/Detector.js"></script>

		<script>

			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

			var composer, renderer;
			var box_mask, box_1, box_2;

			init();
			animate();

			function init() {

				var camera_mask = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
				camera_mask.position.z = 6;
				var camera_1 = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
				camera_1.position.z = 6;
				var camera_2 = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
				camera_2.position.z = 6;

				var scene_mask = new THREE.Scene();
				var scene_1 = new THREE.Scene();
				var scene_2 = new THREE.Scene();

				scene_mask.background = new THREE.Color( 0x000000 );
				scene_1.background = new THREE.Color( 0xffffff );
				scene_2.background = new THREE.Color( 0x000000 );

				var box_mask_1 = new THREE.CircleGeometry( 2, 4 );
				var box_mask_2 = new THREE.CircleGeometry( 2, 4 );

				var singleGeometry_mask = new THREE.Geometry();

				var boxMesh_mask_1 = new THREE.Mesh(box_mask_1);
				boxMesh_mask_1.position.z = 1;
				var boxMesh_mask_2 = new THREE.Mesh(box_mask_2);
				boxMesh_mask_2.rotation.y = Math.PI;
				boxMesh_mask_2.position.z = -1;

				boxMesh_mask_1.updateMatrix(); // as needed
				singleGeometry_mask.merge(boxMesh_mask_1.geometry, boxMesh_mask_1.matrix);
				boxMesh_mask_2.updateMatrix(); // as needed
				singleGeometry_mask.merge(boxMesh_mask_2.geometry, boxMesh_mask_2.matrix);

				var material_mask = new THREE.MeshBasicMaterial({color: 0xffffff});
				box_mask = new THREE.Mesh(singleGeometry_mask, material_mask);

				scene_mask.add( box_mask );

				var box_1_1 = new THREE.CircleGeometry( 2, 4 );
				var box_1_2 = new THREE.CircleGeometry( 2, 4 );

				var singleGeometry_1 = new THREE.Geometry();

				var boxMesh_1_1 = new THREE.Mesh(box_1_1);
				boxMesh_1_1.position.z = -1;
				var boxMesh_1_2 = new THREE.Mesh(box_1_2);
				boxMesh_1_2.rotation.y = Math.PI;
				boxMesh_1_2.position.z = 1;

				boxMesh_1_1.updateMatrix();
				singleGeometry_1.merge(boxMesh_1_1.geometry, boxMesh_1_1.matrix);
				boxMesh_1_2.updateMatrix();
				singleGeometry_1.merge(boxMesh_1_2.geometry, boxMesh_1_2.matrix);

				var material_1 = new THREE.MeshBasicMaterial({color: 0x000000});
				box_1 = new THREE.Mesh(singleGeometry_1, material_1);

				scene_1.add( box_1 );

				var box_2_1 = new THREE.CircleGeometry( 2, 4 );
				var box_2_2 = new THREE.CircleGeometry( 2, 4 );

				var singleGeometry_2 = new THREE.Geometry();

				var boxMesh_2_1 = new THREE.Mesh(box_2_1);
				boxMesh_2_1.position.z = -1;
				var boxMesh_2_2 = new THREE.Mesh(box_2_2);
				boxMesh_2_2.rotation.y = Math.PI;
				boxMesh_2_2.position.z = 1;

				boxMesh_2_1.updateMatrix();
				singleGeometry_2.merge(boxMesh_2_1.geometry, boxMesh_2_1.matrix);

				boxMesh_2_2.updateMatrix();
				singleGeometry_2.merge(boxMesh_2_2.geometry, boxMesh_2_2.matrix);

				var material_2 = new THREE.MeshBasicMaterial({color: 0xffffff});
				box_2 = new THREE.Mesh(singleGeometry_2, material_2);

				scene_2.add( box_2 );

				renderer = new THREE.WebGLRenderer();
				renderer.setClearColor( 0xffffff );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				renderer.autoClear = false;
				document.body.appendChild( renderer.domElement );

				var clearPass = new THREE.ClearPass();
				var clearMaskPass = new THREE.ClearMaskPass();
				var maskPass = new THREE.MaskPass( scene_mask, camera_mask );
				var renderPass_1 = new THREE.RenderPass( scene_1, camera_1 );
				var renderPass_2 = new THREE.RenderPass( scene_2, camera_2 );
				var outputPass = new THREE.ShaderPass( THREE.CopyShader );
				outputPass.renderToScreen = true;

				var parameters = {
					minFilter: THREE.LinearFilter,
					magFilter: THREE.LinearFilter,
					format: THREE.RGBFormat,
					stencilBuffer: true
				};

				var renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, parameters );

				composer = new THREE.EffectComposer( renderer , renderTarget );
				composer.addPass( clearPass );
				composer.addPass( renderPass_1 );
				composer.addPass( maskPass );
				composer.addPass( renderPass_2 );
				composer.addPass( clearMaskPass );
				composer.addPass( outputPass );

			}

			function animate() {

				requestAnimationFrame( animate );

				var time = performance.now() * 0.001  * 2;

				box_mask.rotation.y = time;
				box_1.rotation.y = time;
				box_2.rotation.y = time;

				renderer.clear();
				composer.render( time );

			}

		</script>
	</body>
</html>

this never works:

composer.addPass( clearPass );
composer.addPass( renderPass_1 );
composer.addPass( maskPass );
composer.addPass( renderPass_2 );
composer.addPass( clearMaskPass );
composer.addPass( outputPass );

if i switch out “renderPass_2” with a THREE.TexturePass it works, but it’s not what I want.

Here is the codepen:

https://codepen.io/oxbits/pen/yEQLGK?editors=0010

Anyone able to combine two renderPasses with a mask?

Should I be using a different approach?

@Mugen87, you referenced the cross-post in stackoverflow.
I read the FAQ and it said:
“Don’t cross-post the same thing in multiple topics.”
I did not think SO was another topic of this forum, so I thought that was ok.
Please let me know.
Thank you.

I’m not sure if it’s possible to achieve your desired effect with MaskPass since it looks like you want to mix both render results. A mask pass just limits the area of rendering via the stencil buffer. So everything you achieve is to render on top of the existing color values in your drawing buffer at certain places.

BTW: If you use RenderPass like in your code, you have to set renderPass.clear to false. Otherwise all data in your render target are cleared when the pass is executed.

1 Like

Is there another approach I should be considering?
Is there a better way to combine 2 render results?

I was looking at these scripts I found :

http://jsfiddle.net/psyrendust/ga13okzz/
http://jsfiddle.net/Eskel/g593q/9

it combines 2 render results.

what am I missing?

Thank you @Mugen87!

I finally got it to work though I’m not sure how!

Take a look:

1 Like