I’m trying to combine the tone mapping effects from this example with the outline effects from this example
The outline effect uses an effect composer and then a call to composer.render();in the animate function. Whereas the tone mapping effect seems to be applied directly to the renderer using renderer.toneMapping = someToneMappingOption; and then a call to renderer.render( scene, camera );
So my question is: is there a way to combine these two effects given that they use two different methods of drawing the scene?
The outline example renders the scene via RenderPass. This is the so called beauty pass. It internally uses the same renderer.render( scene, camera ); call you normally use in your three.js app. The post-processing effect is then applied with a subsequent pass. Hence, it should be no problem to combine both approaches.
However, there might be post-processing setups where you can use the inline tone mapping and gamma correction features of the renderer. Meaning you have to apply tone mapping and gamma correction as a post-processing pass at the end of your pass chain. That’s because certain passes expect the color values in linear color space, not tone mapped. In this case, you might want to use an approach similar to webgl_shaders_tonemapping and apply tone mapping via post-processing.
The post-processing effect is then applied with a subsequent pass. Hence, it should be no problem to combine both approaches
How would I go about combining?
Here is how I’ve tried to do my post processing setup:
setPostProcessing() {
//Tone mapping:
this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
this.renderer.toneMappingExposure = 0.9;
this.renderer.toneMappingWhitePoint = 1.0;
//Render pass:
this.composer = new EffectComposer(this.renderer);
let renderPass = new RenderPass(this.scene, this.camera);
this.composer.addPass(renderPass);
//Outline effect:
this.outlinePass = new OutlinePass(new THREE.Vector2(this.playerCanvas.clientWidth, this.playerCanvas.clientHeight), this.scene, this.camera);
let toneMappingPass = new AdaptiveToneMappingPass(true, 256);
this.composer.addPass(this.outlinePass);
this.composer.addPass(toneMappingPass);
}
then in my animate function If I call this.renderer.render( this.scene, this.camera ); here is what I see (tone mapping working fine, but no selection outline):
Ah wait, I made a mistake. If you configure tone mapping like that, it will apply globally to all calls of renderer.render() (at least for all built-in materials). This is not necessarily something you want in this post-processing setup.
I’m afraid you have to use a tone mapping and gamma correction pass for this scenario.
Thanks again… I appreciate you steering me in the right direction. But I have to admit I’m a bit useless when it comes to shader stuff… How would I go about turning the code you’ve linked into a ShaderPass that I can then use with my effect composer?
I’ve realized right now that there is already ACESFilmicToneMappingShader. You can use this file to create an instance of ShaderPass and then add it to your post-processing chain.
Thanks for that, I’m still getting issues with this however:
I initialise my post processing like this:
import { ACESFilmicToneMappingShader } from "./ACESFilmicToneMappingShader";
setPostProcessing(){
//Render pass:
this.composer = new EffectComposer(this.renderer);
let renderPass = new RenderPass(this.scene, this.camera);
this.composer.addPass(renderPass);
//Outline effect:
this.outlinePass = new OutlinePass(new THREE.Vector2(this.playerCanvas.clientWidth, this.playerCanvas.clientHeight), this.scene, this.camera);
this.composer.addPass(this.outlinePass);
//Tone mapping
let tmPass = new ShaderPass(ACESFilmicToneMappingShader);
this.composer.addPass(tmPass);
}
where my ACESFilmicToneMappingShader.ts is just a copy from the file you linked
Now I am seeing nothing in the 3d view and an error in the console:
THREE.WebGLProgram: shader error: 0 35715 false gl.getProgramInfoLog invalid shaders THREE.WebGLShader: gl.getShaderInfoLog() fragment ERROR: 0:116: ‘ACESFilmicToneMapping’ : function already has a body