How to add post-processing to viewport of three.js editor

Hello.
I’m customizing three.js editor, and now I’m struggling to add post-processing to current three.js editor viewport.
Please help me.
Thanks in advance.

Have you looked at how the Postprocessing examples handle it?

Thanks, marquizzo.
As you know, three.js editor viewport is a special case.
In Viewport.js, renderer renders two scenes(scene, sceneHelpers).
I need to replace render.render() with composer.render(), so I added two RenderPass objects to EffectComposer, but this did not work at all.
Please help with this.

Regards.

Without providing more information, it’s not possible to help. You might get more feedback by sharing your progress of work as a GitHub repo.

Sorry for less information. Here are some code snippets of my work.

...
var composer = null;
...
signals.rendererChanged.add( function ( newRenderer, newPmremGenerator ) {

    if ( renderer !== null ) {

        container.dom.removeChild( renderer.domElement );

    }

    renderer = newRenderer;
    pmremGenerator = newPmremGenerator;

    renderer.autoClear = false;
    renderer.autoUpdateScene = false;
    renderer.outputEncoding = THREE.sRGBEncoding;
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );

    container.dom.appendChild( renderer.domElement );

    composer = new EffectComposer( renderer );
    composer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
    composer.addPass( new RenderPass( scene, camera ) );
    composer.addPass( new RenderPass( sceneHelpers, camera) );
        
    render();

} );
...
function render() {

    startTime = performance.now();

    scene.updateMatrixWorld();
    sceneHelpers.updateMatrixWorld();

    composer.render();

    endTime = performance.now();
    var frametime = endTime - startTime;
    editor.signals.sceneRendered.dispatch( frametime );

}

But only scene helpers are rendered in the output screen.
Looking forward to hearing from you.

Thanks.

RenderPass has a clear property which is set to true by default. Meaning when having two render passes, the result of the previous pass is cleared. Try to set the property to false for your second render pass.

It might also be necessary to set renderer.autoClearDepth to false and maybe add a clear pass at the beginning of your pass chain.

Sorry, but the solution doesn’t seem to work. I’ve just changed renderChanged signal event and re-run the application but only scene helpers are rendered again.

signals.rendererChanged.add( function ( newRenderer, newPmremGenerator ) {

	if ( renderer !== null ) {

		container.dom.removeChild( renderer.domElement );

	}

	if ( composer !== null ) {

		composer = null;

	}

	renderer = newRenderer;
	pmremGenerator = newPmremGenerator;

	renderer.autoClear = false;
	renderer.autoUpdateScene = false;
	renderer.autoClearDepth = false;
	renderer.outputEncoding = THREE.sRGBEncoding;
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );

	container.dom.appendChild( renderer.domElement );

	composer = new EffectComposer( renderer );
	composer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );

	var scenePass = new RenderPass( scene, camera );
	composer.addPass( scenePass );
	
	var helpersPass = new RenderPass( sceneHelpers, camera );
	helpersPass.clear = false;
	composer.addPass( helpersPass );

	render();

} );

Then please share your entire project as a GitHub repo. Without debugging your modified editor, it will be hard provide more feedback.

I had a try at implementing postprocessing in the viewport, so far I managed to either get no effects (only renderPass) or only one of the two contexts (scene or scenehelper). I tried most of the options I had in mind, including having 2 effect composers or switch the renderpass context from scene to sceneHelpers at runtime with no luck.

Jun-02-2020 13-39-30

From there, I’d say the problem is more likely in how the various passes / contexts are dealt with within the composer, which may be effect or shader dependant (i’ve seen some differences). Also, I see few added value in having postprocessing in the viewport, you’d more likely want it in the player (which is easier to implement). Last, for the few unexplored steps I had in mind:

  • include scenehelpers elements in the scene object (very dirty)
  • try to deal manually with the composer passes sequence