hello everyone!
I want to use the effectcomposer to render two scenes, just like using the webgl renderer to achieve the same function, like this
renderer.render(scene, camera)
renderer.autoClear = false;
renderer.render(scene2, camera);
renderer.autoClear = true;
What should I do?
autoClear
is a flag that you normally set just once after creating the renderer. Why are you using it in this way?
Qiumeng12:
renderer.autoClear
It is used when rendering two scenes in the editor source code. If I want to render two scenes, what should be the correct method
Set it just once and use this pattern:
const renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
function animate() {
requestAnimationFrame( animate );
renderer.clear(); // manual clear
renderer.render(scene, camera);
renderer.render(scene2, camera);
In context of post processing you normally don’t need two render calls. Have you considered to use two instances of RenderPass
?
If one scene needs to use post and the other scene does not need to use post, how should we render two scenes at the same time. It doesn’t work
const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(
new THREE.Vector2(dom.offsetWidth, dom.offsetHeight),
1.5,
0.4,
0.85
);
composer = new EffectComposer(renderer);
composer.addPass(renderScene);
composer.addPass(bloomPass);
renderer.autoClear = false;
function animate() {
requestAnimationFrame( animate );
renderer.clear();
composer.render();
renderer.render(scene2, camera);
}
@Qiumeng12
Are you looking for something like selective bloom? three.js examples
I saw this demo, but all object3d in it are in one scene. I need two scenes to distinguish. Is there any other solution besides this demo?One scene stores my objects and the other stores helpers.
Harold
August 23, 2021, 10:40am
8
I think the use of layers might be what you’re really after? Instead of rendering two scenes, add two groups or object3d instances to your scene where one contains your meshes and the other your helpers. Using layers you can simply turn a layer on or off depending on what you want to render.
3 Likes
Use renderer_1 and renderer_2
If the scene where I store objects needs post-processing, can the use of that group help me solve the problem?
I don’t quite understand what you mean. Can you be more detailed?
Harold
August 24, 2021, 6:18am
12
Sure, you don’t need 2 renderers. Just render the first layer first and store that result in a render target. Then you switch the layers and render the second one and do your post processing. Then as a final post processing pass, you simply blend the final results of both layers together
OK, I try to use this method to achieve it. I really feel your patient reply.
const renderScene = new RenderPass(scene, camera);
const renderScene2 = new RenderPass(scene2, camera);
const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
const pixelRatio = renderer.getPixelRatio();
const fxaaPass = new ShaderPass(FXAAShader);
fxaaPass.material.uniforms['resolution'].value.x = 1 / (window.innerWidth * pixelRatio);
fxaaPass.material.uniforms['resolution'].value.y = 1 / (window.innerHeight * pixelRatio);
const bloomComposer = new EffectComposer(renderer);
bloomComposer.renderToScreen = false;
bloomComposer.addPass(renderScene);
bloomComposer.addPass(bloomPass);
const bloomComposer2 = new EffectComposer(renderer);
bloomComposer2.renderToScreen = false;
bloomComposer2.addPass(renderScene2);
bloomComposer2.addPass(fxaaPass);
const finalPass = new ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
defines: {}
}), "baseTexture"
);
finalPass.needsSwap = true;
const finalPass2 = new ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer2.renderTarget2.texture }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
defines: {}
}), "baseTexture"
);
finalPass2.needsSwap = true;
const finalComposer = new EffectComposer(renderer);
finalComposer.addPass(renderScene)
finalComposer.addPass(finalPass);
finalComposer.addPass(finalPass2);
finalComposer.addPass(fxaaPass);
I’m not sure if my approach is reasonable, but it does help me render things in two scenes. What do you think? @Mugen87 @prisoner849 @Harold
const renderScene = new RenderPass(scene, camera);
let target = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight);
renderer.clear()
renderer.setRenderTarget(target);
renderer.render(scene2, camera);
renderer.setRenderTarget(null)
bloomComposer.render()//This is the scene that needs post-processing for rendering
const finalPass = new ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
defines: {}
}), "baseTexture"
);
finalPass.needsSwap = true;
const finalPass2 = new ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: target.texture }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
defines: {}
}), "baseTexture2"
);
finalPass2.needsSwap = true;
const finalComposer = new EffectComposer(renderer);
finalComposer.addPass(renderScene)
finalComposer.addPass(finalPass);
finalComposer.addPass(finalPass2);
finalComposer.render()
What I want to know is whether you want to add finalpass and finalpass2 to effectcomposer by mixing the rendering results of two scenes.
How do I mix the final results of two layers?
Harold
August 25, 2021, 9:40am
17
You could use the blend shader for that and use the result of one pass as input. You should be able to find some examples that do the same thing. I know the SSAO pass does this, just to point you in the right direction.
I can find too few cases about this
Oreo
August 19, 2023, 5:53am
19
Hello, I have the same problem as you. Have you solved it?