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

3
我正在使用three.js中的Composer创建复杂场景。我想知道是否可以在两个具有不同composer效果的场景之间切换。为了获得某种视角,我创建了一个示例,允许您在两个通常呈现的场景之间切换。 Two scene example 根据我对composer工作原理的理解,您需要创建其实例,然后应用渲染通道,如下所示:
    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); 

然后像这样应用Composer渲染器:
    this.composer.render();

那么我的问题是,如果我有第二个场景,其中有一个作曲家实例,那么我该如何:

  1. 使用相同的渲染器(如果可能)
  2. 像我的示例一样在场景1和场景2之间切换。
2个回答

5

您可以像切换场景一样切换效果合成器。代码示例如下:

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();

如果需要,您甚至可以重复使用某些渲染通道。


非常抱歉没有及时回复您,感谢您提供的示例,我进行了快速实现并通过在效果合成器中切换场景使其工作。正如您所提到的,我可以使用多个EffectComposers,我只是试图通过您的示例来想象它的样子,但使用Effect composer的方法对我来说都是新的。是否可能提供一个小的代码片段来展示这是什么样子的。非常感谢。 - W9914420
我不太了解你的使用情况,所以很难就架构问题提出建议。你可以将composer附加到场景对象上,这样你只需要切换场景并始终使用activeScene.composer.render()进行渲染。关于Effect-Composer本身的更多细节,我建议您添加一个单独的问题(另外,也许这会有所帮助:https://github.com/hughsk/three-effectcomposer)。 - Martin Schuhfuß
是的,我认为activeScene.composer就是我要找的。谢谢你的提示和修改示例,我将把我的解决方案添加到我的问题中 :) - W9914420
请看一下我的解决方案,非常感谢您的建议。祝一切顺利 :) - W9914420

3

两位古典作曲家

在开始之前,我要感谢Martin Schuhfuß,他提供了这个方案的见解。

免责声明

我不是JavaScript的专家或专业程序员,我并不认为这是唯一的方法,我的演示应该以抽象的方式来看待。我的想法仅是解释解决方案所基于的理论前提,其实现取决于您自己的架构。

架构

在本例中,我使用了OOP方法,您应该能够将解决方案操纵为您正在使用的任何方法。

方法

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

1.创建一个作曲家对象。

因此,我创建了一个对象来放置作曲家对象,并在参考我的效果时保持漂亮的“作曲家”名称约定。

This.composer = {};

2. 创建一个函数,用于初始化与场景相关的 RenderPasses。

重要的是要记住,在调用我们的 composer 之前,我们需要先定义和初始化 RenderPasses。RenderPasses 允许我们添加我们想要的效果(即所谓的着色器)。在我的例子中,我有两个场景,因此我需要创建:

  1. 两个 RenderPasses。
  2. 一个 RenderPass 复制了该场景。
  3. 另一个 RenderPass 对其场景应用了一种棕褐色的效果。

代码示例:

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. 确定在架构中添加通道的位置

现在,我们需要添加通道声明(来自composer的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();

请注意,“activeScene”部分是指实际使用的场景。这允许我们更改场景。
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;

结论 这是我实现此效果的方法,但如果有更好或替代的方法,请添加到讨论中并分享。


只想说感谢您撰写如此详细的答案。 - ty.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接