Javascript 使用THREE.js中的相同渲染器在多个THREE.EffectComposer场景之间切换
我正在用three.js中的Composer创建复杂的场景。 我想知道是否有可能在两个具有不同作曲家效果的场景之间切换。为了获得某种透视效果,我创建了一个示例,它允许您在两个正常渲染的场景之间切换 根据我对composer工作原理的理解,您可以创建其实例,然后应用渲染过程,如下所示:Javascript 使用THREE.js中的相同渲染器在多个THREE.EffectComposer场景之间切换,javascript,three.js,Javascript,Three.js,我正在用three.js中的Composer创建复杂的场景。 我想知道是否有可能在两个具有不同作曲家效果的场景之间切换。为了获得某种透视效果,我创建了一个示例,它允许您在两个正常渲染的场景之间切换 根据我对composer工作原理的理解,您可以创建其实例,然后应用渲染过程,如下所示: this.composer = new THREE.EffectComposer(this.renderer.default.init); this.renderPass = new THREE.
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();
所以我的问题是,如果我有第二个场景是作曲家的实例,那么我怎么能:
您可以按照从一个场景切换到另一个场景的相同方式,从一个effectComposer切换到另一个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();
如果愿意,您甚至可以重用某些渲染过程。
因此,在我开始之前,我只想对谁提供了这个解决方案的见解大喊一声
免责声明
我不是javascript方面的专家或专业程序员,我绝不建议这是唯一的方法,我的演示应该以抽象的方式进行。我的想法只是解释了解决方案所基于的理论前提,而这一前提的实现将取决于您自己的体系结构
架构
在本例中,我使用的是OOP方法,您应该能够将解决方案操作到您正在使用的任何方法
方法
因此,根据Martin当前的示例,您可以看到我们可以将composer属性/对象添加到场景对象,这意味着场景可以继承相同的composer效果,这非常出色,但是在我的例子中,我有许多具有不同composer效果的场景,因此我需要重新思考这个问题
1。创建一个Composer对象。
因此,我创建了一个对象,将composer对象放入其中,并在引用我的效果时保持良好的“composer”名称约定
This.composer = {};
2。创建一个函数来初始化相关场景的渲染过程。
因此,重要的是要记住,在调用编写器之前,我们需要首先定义并初始化renderPass。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。定义在体系结构中添加过程的位置
所以现在我们需要添加pass声明(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渲染方法
因此,这一行代码需要放在进行composer处理的任何位置(这取决于您的设置)
请注意,“ActiveCcene”部分引用了当时使用的实际场景。正是这一点让我们能够改变场景
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;
结论
这是我实现此效果的方法,但如果有更好或替代方法,请添加到讨论中并与大家分享。我很抱歉没有尽快回复您,感谢您提供此示例,我快速实现了,并通过在effect composer中切换场景来实现,正如您提到的,我可以使用多个EffectComposer,我只是想通过您的示例来形象化这将是什么样子,但使用EffectComposer的方法对我来说还是全新的。有没有可能提供一个小的代码片段来说明这一点。很多感谢我并不真正了解你的用例,所以很难提出关于架构的建议。您可以将composer附加到场景对象,这样您只需切换场景并始终使用
activeScene.composer.render()
进行渲染。关于特效作曲家本身的更多细节,我建议添加一个单独的问题(也可能有帮助:)是的,我认为activeScene.Composer就是我要找的。对于提示和编辑示例,我将在我的问题中添加我的解决方案:)请查看我的解决方案,以及许多TNX,以获得您的建议。和平:)我只想说谢谢你写了这么详细的答案。
// 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;