使用three.js中的相同渲染器在多个THREE.EffectComposer场景之间切换

时间:2017-05-29 19:11:33

标签: javascript three.js

我正在使用三个.js中的Composer创建复杂场景。 我想知道是否可以在两个具有不同作曲家效果的场景之间切换。为了获得某种视角,我创建了一个示例,允许您在两个正常渲染的场景之间切换。

Two scene example

根据我对作曲家工作原理的理解,你创建了一个实例,然后像这样应用渲染过程:

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

然后应用如下的作曲家渲染:

    this.composer.render();

所以我的问题是,如果我有第二个场景,作曲家实例我怎么能:

  1. 使用相同的渲染器(如果可能)
  2. 在场景1和场景2之间切换,就像我的例子一样。
  3. 我知道这是相当抽象的,但任何提示,观点都会受到赞赏。

    Tnxs

2 个答案:

答案 0 :(得分:4)

您可以像从一个场景切换到另一个场景一样从一个effectComposer切换到另一个。所以这将是这样的:

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

const composers = scenes.map(function(scene) {
  const composer = new THREE.EffectComposer(renderer);

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

  scene.composer = composer;
  return composer;
});

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

如果你愿意,你甚至可以重复使用某些渲染通道。

答案 1 :(得分:1)

Two classical composers

所以在我开始之前,我只想向Martin Schuhfuß发出呼喊,他们提供了对此解决方案的见解。

<强>声明

我不是javascript中的专家或专业程序员,我绝不建议这是这样做的唯一方法,我的演示文稿应该以抽象的方式呈现。我的想法只能解释解决方案所依据的理论前提,并且实现将取决于您自己的架构。

<强>建筑

我在这个例子中使用OOP方法,你应该能够将解决方案操作到你正在使用的任何方法。

方式

因此,基于Martin的当前示例,您可以看到我们能够将composer属性/对象添加到场景对象中,这意味着场景可以继承相同的作曲家效果,但是在我的情况下我有很多不同的场景作曲家效应所以我需要重新思考这个问题。

<强> 1。创建Composer对象。

所以我创建了一个对象,在引用我的效果时将作曲家对象放入并保持良好的“作曲家”名称约定。

This.composer = {};

<强> 2。创建一个函数以使用相关场景初始化RenderPasses。

因此,重要的是要记住,在调用我们的作曲家之前,我们需要先定义并初始化RenderPasses。 RenderPasses允许我们将我们想要的效果属于(知道着色器)。在我的例子中,我有两个场景,因此我需要创建:

  1. 两个RenderPasses。
  2. One RenderPass复制了场景。
  3. 另一个RenderPass将棕褐色效果应用于其场景。
  4. 代码示例:

    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;
    
    } 
    

    注意:由于法律原因,必须重命名某些文件名,但关键是此函数被调用为更大的对象。

    第3。创建一个开始功能,并让作曲家分配到场景

    此功能的目的只是为了演示我们如何将它们组合在一起。所以我们拥有的代码是这样的。

    // so we create an object to use for reference for EffectComposer objects
        this.composer = {};
    
    
    // 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 composer for scene 1
        this.composer.ui = new THREE.EffectComposer(stackoverflow.webgl.renderer.default.init);
    
    // Create a new composer for scene 1
        this.composer.ui2 = new THREE.EffectComposer(stackoverflow.webgl.renderer.default.init);
    
    // Now here is the cool stuff you can assign a composer to each scene
    
        this.scene.default.composer = stackoverflow.webgl.composer.ui;
        this.scene.test.composer = stackoverflow.webgl.composer.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.composer);
    
    // 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。定义在架构中添加传递的位置

    所以现在我们需要为我们的效果添加传递声明(来自作曲家的addpass函数)

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

    <强> 5。添加EffectComposer渲染方法

    所以这段代码需要放在你进行作曲家处理的地方(取决于你的设置)。

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

    请注意,'activecScene'部分引用当时使用的实际场景。这是允许我们改变场景的。

    <强> 6。创建一个按钮并在场景之间切换

    所以我在dat.gui实例中创建了两个按钮,允许我在两个场景之间切换。

    再次,您可以创建一个按钮,随时随地运行。

    // 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;
    

    <强>结论 这是我实现这种效果的方法,但如果有更好的或替代的方式,请加入讨论并分享。