three.js icon indicating copy to clipboard operation
three.js copied to clipboard

Introduce renderer.setPostProcessing()

Open takahirox opened this issue 5 years ago • 4 comments

From https://github.com/mrdoob/three.js/pull/15840#issuecomment-503810517

I'm working on renderer.setPostProcessing() API trial, that is supporting post processing API in core. I want feedbacks so this PR is draft for now.

Suggested API

// enable post processing
renderer.setPostProcessing( [ effect1, effect2 ] ); // effects are existing Pass instances
// disable post processing
renderer.setPostProcessing( [] );

Example

Unreal bloom post processing example.

import {
  PerspectiveCamera,
  Scene,
  WebGLRenderer,
  ...
} from '../build/three.module.js';
import { UneralBloomPass } from './jsm/postprocessing/UnrealBloomPass.js';

...

var bloomPass = new UnrealBloomPass( params );
renderer.setPostProcessing( [ bloomPass ] );

function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth, window.innerHeight );
}

function render() {
    requestAnimationFrame( render );
    renderer.render( scene, camera );
}

window.addEventListener( 'resize', onWindowResize );
render();

Changes

I'm trying to move EffectComposer in core so far.

src/renderers/postprocessing
  - EffectComposer.js
  - passes/
    - Pass.js, ShaderPass.js, MaskPass.js
  - shaders/
    - CopyShader.js

Advantages

  • Not many brand new code by reusing EffectComposer.
  • User code will be simpler with the new API because they no longer need to take care composer (see webgl_postprocessing)

Discussion

  • The new API expects that first rendering a scene and then applying post processing effects on it. It doesn't cover all the current EffectComposer use cases. In some use cases RenderPass (rendering a scene) is a second or later pass (e.g. webgl_postprocessing_backgrounds example).
composer.addPass( fooPass ); 
composer.addPass( renderPass ); // rendering a scene
composer.addPass( barPass );

There might be more complex cases. For compatibility, I'm thinking about exporting EffectComposer from src/Three.js. Good point is users who still want to directly use EffectComposer for complex use cases, they can keep using it without big their code change. They just needs to change the location where importing the composer from. Bad point is there will be two ways to apply post processing for users, renderer.setPostProcessing() and EffectComposer. It might be confusing.

/cc @mrdoob

takahirox avatar Jan 07 '20 10:01 takahirox

Other than developer convenience and a simpler API, are there more advantages to doing this? I don't know the current state of using EffectComposer with WebXR, for example... is that hard now? easier or harder with this API?


If we do prefer the proposed API but simply want to keep EffectComposer out of core, one option might be to let WebGLRenderer be given a composer by the user. Similar to how Loader.setHandlers(...) lets users "install" loaders that aren't in core. For example:

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';

// ...

renderer.setEffectComposer( new EffectComposer() );
renderer.setPasses( [ ... ] );

donmccurdy avatar Jan 08 '20 02:01 donmccurdy

Thanks for the comments. Before replying I'd like to ask @mrdoob if the suggested API is what he expects because the new API is originally his idea and if I misunderstood his idea the discussion can be mess so just in case.

takahirox avatar Jan 08 '20 23:01 takahirox

Can't comment on the direction to take, but PostProcessing could do with some TLC. Some elements are quite confusing.

For example variables are named "readBuffer" and "writeBuffer", but both are then written to and read to! I propose "bufferA" and bufferB".

Also RenderPass.render takes readBuffer as a parameter, but writes to it! This dirties RenderPass with logic from EffectComposer. I propose render: function ( renderer, unused, writeBuffer /*, deltaTime, maskActive */ ) { I understand the author was perhaps trying to emulate a "function overriding" mechanism, but that feels constructed.

CreaticDD avatar Jan 09 '20 21:01 CreaticDD

@donutcoffee I think your post better fits to the following discussion: #12115

Mugen87 avatar Jan 10 '20 09:01 Mugen87

Closing in favor of https://github.com/mrdoob/three.js/issues/12115#issuecomment-2429240760

sunag avatar Oct 29 '25 16:10 sunag