最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Toggle between multiple THREE.EffectComposer scenes using the same renderer in three.js - Stack Overflow

programmeradmin2浏览0评论

I am in the process of creating plex scenes with Composer in three.js. I am wanting to know if it is possible to switch between two scenes that have different poser effects attributed to them. To gain some sort of perspective I have created an example which allows you to toggle between two normally rendered scenes.

Two scene example

From my understanding of how poser works you create an instance of it and then apply a render pass like so:

    thisposer = new THREE.EffectComposer(this.renderer.default.init);
    this.renderPass = new THREE.RenderPass(this.stage,  this.camera);
    this.renderPass.renderToScreen = true;
    thisposer.addPass(this.renderPass); 

and then apply a poser render like so:

    thisposer.render();

So my question is if I have a second scene which a poser instance how can I then:

  1. Use the same renderer (if possible)
  2. Toggle between scene 1 and scene 2 like in a similar fashion to my example.

I am in the process of creating plex scenes with Composer in three.js. I am wanting to know if it is possible to switch between two scenes that have different poser effects attributed to them. To gain some sort of perspective I have created an example which allows you to toggle between two normally rendered scenes.

Two scene example

From my understanding of how poser works you create an instance of it and then apply a render pass like so:

    this.poser = new THREE.EffectComposer(this.renderer.default.init);
    this.renderPass = new THREE.RenderPass(this.stage,  this.camera);
    this.renderPass.renderToScreen = true;
    this.poser.addPass(this.renderPass); 

and then apply a poser render like so:

    this.poser.render();

So my question is if I have a second scene which a poser instance how can I then:

  1. Use the same renderer (if possible)
  2. Toggle between scene 1 and scene 2 like in a similar fashion to my example.
Share Improve this question edited Apr 6, 2021 at 3:38 Nimantha 6,4866 gold badges31 silver badges76 bronze badges asked May 29, 2017 at 19:11 W9914420W9914420 7152 gold badges12 silver badges26 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

You can just switch from one effectComposer to another one the same way as you switch from one scene to the other. So that would be something like this:

const scenes = [
  new THREE.Scene(), 
  new THREE.Scene()
];

const posers = scenes.map(function(scene) {
  const poser = new THREE.EffectComposer(renderer);

  // configure render-passes
  const renderpass = new THREE.RenderPass(scene, camera);
  renderpass.renderToScreen = true;
  poser.addPass(renderpass);

  scene.poser = poser;
  return poser;
});

// then use the poser for the scene
let activeScene = scenes[0];
activeScene.poser.render();

You should even be able to reuse certain render-passes if you want to.

So before I begin I just want to give a shout out to Martin Schuhfuß who provided the insight to this solution.

Disclaimer

I am not an expert or professional Programmer in javascript and I by no means suggest that this is the only way of doing this, my presentation should be taken in an abstract fashion. My thoughts only explain the theoretical premises for which the solution is based on and implementation of this will depend upon your own architecture.

Architecture

I am using an OOP method in this example, you should be able to manipulate the solution to whatever method you are using.

Method

So based on Martin’s current example you can see that we able to add the poser property/object to our scene object this means that scenes could inherit the same poser effects which is brilliant, however In my case I have many scenes with different poser effects so I needed to rethink the problem.

1. Create a Composer object.

So I created an object to put poser objects in and keep to the nice ‘poser’ name convention when reference my effects.

This.poser = {};

2. Create a function to initialise RenderPasses with the concerning scenes.

So it is important to remember that we need to define and initailse the RenderPasses first before will call our poser. RenderPasses allows us to attribute the effects (know has shaders) that we want. In my example I have two scenes therefore I needed to create:

  1. Two RenderPasses.
  2. One RenderPass copied the scene.
  3. The other RenderPass applied a sepia effect to its scene.

Example of Code:

this.init = function() {

stackoverflow.webgl.pass.base = new THREE.RenderPass(stackoverflow.webgl.scene.default, 
stackoverflow.webgl.camera);

stackoverflow.webgl.pass.base2 = new THREE.RenderPass(stackoverflow.webgl.scene.test, 
stackoverflow.webgl.camera);

stackoverflow.webgl.pass.sepia = new 
THREE.ShaderPass(THREE.SepiaShader);
stackoverflow.webgl.pass.sepia.renderToScreen = true;

stackoverflow.webgl.pass.copy = new THREE.ShaderPass(THREE.CopyShader);
stackoverflow.webgl.pass.copy.renderToScreen = true;

} 

Note: some file names had to be renamed due to legal reason, but the point being is that this function is called into a larger object.

3. Create a start function and lets assign posers to scenes

The purpose of this function is just to demonstrate how we bine it all together. So the code that we have is something like this.

// so we create an object to use for reference for EffectComposer objects
    this.poser = {};


// this property is used to set the scene that we want
// this.scene.default = new THREE.Scene();

    this.activeScene = this.scene.default;

// this function is just a wrapper for our code

    this.start = function () {

// so call our initialise our RenderPasses

    stackoverflow.webgl.pass.init();

// my own method of seting up the WebGLRenderer scene (You do it your Way!)
    stackoverflow.webgl.renderer.default.setup;

// Create a new poser for scene 1
    this.poser.ui = new THREE.EffectComposer(stackoverflow.webgl.renderer.default.init);

// Create a new poser for scene 1
    this.poser.ui2 = new THREE.EffectComposer(stackoverflow.webgl.renderer.default.init);

// Now here is the cool stuff you can assign a poser to each scene

    this.scene.default.poser = stackoverflow.webgl.poser.ui;
    this.scene.test.poser = stackoverflow.webgl.poser.ui2;

// and i always like to check that things happen and they do ;)

    console.log(this.scene.default);
    console.log(this.scene.test);
    console.log(this.poser);

// so  you will need to add the passes some place, I created a function call render, (you do according to your code structure)

    stackoverflow.webgl.render();

    }

4. Define where you add the passes in your architecture

So now we will need to add the pass declarations (addpass functions from poser) for our effects to take place.

this.render = function () {    
stackoverflow.webgl.poser.ui.addPass(stackoverflow.webgl.pass.base);        
stackoverflow.webgl.poser.ui.addPass(stackoverflow.webgl.pass.copy);      
stackoverflow.webgl.poser.ui2.addPass(stackoverflow.webgl.pass.base2);
stackoverflow.webgl.poser.ui2.addPass(stackoverflow.webgl.pass.sepia);
};

5. Add the EffectComposer render method

So this line of code will need to be placed wherever you do the poser processing (that depends on your setup).

stackoverflow.webgl.activeScene.poser.render();

Please take note that the ‘activecScene’ part makes reference to the actual scene used at the time. It is this that allows us to change the scene.

6. Create a button and toggle between the scenes

So I created two buttons in a dat.gui instance that allows me to toggle between the two scenes.

Again you can create a button, function whatever you like.

// again just change the vale of active scene to the scene you wish to change to

// button 1 value will be something like this:
stackoverflow.webgl.activeScene = stackoverflow.webgl.scene.test;

// button 2 value will takes us back to scene 1
stackoverflow.webgl.activeScene = stackoverflow.webgl.scene.default;

Conclusion This is my method of achieving this effect, but if there are better or alternative ways then please add to the discussion and share.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论