aframe
aframe copied to clipboard
how to use EffectComposer/UnrealBloomPass in Aframe
Description:
i write the threejs code in vue + Aframe, but it`s not work and no error
mounted(){
this.sceneElement = document.querySelector("a-scene");
if (this.sceneElement.hasLoaded) {
this.senceLoaded2();
} else {
this.sceneElement.addEventListener('loaded', this.senceLoaded2);
}
},
method:{
senceLoaded2 () {
var params = {
exposure: 1.5,
bloomStrength: 100,
bloomThreshold: 0,
bloomRadius: 0.8
}
let renderer = this.sceneElement.renderer
let camera = this.sceneElement.camera
let scene = this.sceneElement.object3D
// 添加渲染场景到渲染器
var renderScene = new window.THREE.RenderPass(scene, camera);
let bloomPass = new window.THREE.UnrealBloomPass(new window.THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);
bloomPass.renderToScreen = true;
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
let composer = new window.THREE.EffectComposer(renderer);
composer.setSize(window.innerWidth, window.innerHeight);
composer.addPass(renderScene);
composer.addPass(bloomPass);
window.AFRAME.effectComposer = composer
// 创建Bloom的Material
let meshMaterialBloom = new window.THREE.MeshBasicMaterial({
color: "blue",
transparent: false,
opacity: 1
});
var geometryBloom = new window.THREE.BoxGeometry(10, 10, 10);
var cubeBloom = new window.THREE.Mesh(geometryBloom, meshMaterialBloom);
// 设置到第二通道
cubeBloom.layers.enable(1);
scene.add(cubeBloom);
},
}
i so rewrited Aframe/core/sence/a-sence.js[function render] on my location, code as
/**
* The render loop.
*
* Updates animations.
* Updates behaviors.
* Renders with request animation frame.
*/
render: {
value: function (time, frame) {
var renderer = this.renderer;
this.frame = frame;
this.delta = this.clock.getDelta();
this.time = this.clock.elapsedTime * 1000;
if (this.isPlaying) { this.tick(this.time, this.delta * 1000); }
var savedBackground = null;
if (this.is('ar-mode')) {
// In AR mode, don't render the default background. Hide it, then
// restore it again after rendering.
savedBackground = this.object3D.background;
this.object3D.background = null;
}
+ if(window.AFRAME.effectComposer){
+ renderer.clear();
+ this.camera.layers.set(window.AFRAME.BLOOM_SCENE);
+ window.AFRAME.effectComposer.render(this.delta);
+ renderer.clearDepth();
+ this.camera.layers.set(window.AFRAME.ENTIRE_SCENE);
+ renderer.render(this.object3D, this.camera);
}
- renderer.render(this.object3D, this.camera);
if (savedBackground) {
this.object3D.background = savedBackground;
}
},
writable: true
}
my copy example1: https://wow.techbrood.com/fiddle/54961
my copy example2: https://blog.csdn.net/qq_39503511/article/details/111029877
need help !
- A-Frame Version: 1.2.0
- Platform / Device: vue/mac pro
- Reproducible Code Snippet or URL:
英语不太好,我就直接写中文了,
以上问题我已经解决,希望对有需要的人有帮助
经过多天研读源码,加上看threejs范例,最终花了五天时间找到了方案【之前没怎么做过这方面底层】 现在有一个建议提给Aframe官方:我们对WebGLRenderer的封装太过死板了,虽然有onBeforeRender和onAfterRender这两个函数,但是不足以支撑我们的特殊场景
1、在我们需要做多通道渲染时候,每个通道都会调用renderer.render(),如果我们想依靠onBeforeRender和onAfterRender解决这一问题,这会导致递归,造成栈溢出,而且a-sence.js中render()的renderer.render(this.object3D, this.camera);调用会冗余 2、如果我们通过修改源码禁用a-sence.js中的play()的renderer.setAnimationLoop(this.render);然后自己去控制render调用,这样看似能解决我们的问题,但是如果项目中有自己写的shader,且自己的shader有法线方向扩散的特效等类似功能,这些功能又会失效,并非一个合理的解决办法
【最终解决方案:核心代码】 1、修改a-sence.js中render()
// 马少杰兼容添加---注意:此方案的引入致使renderer的onBeforeRender和onAfterRender这两个钩子函数已不可再使用,因为bloomComposer和finalComposer的render()都会默认调用renderer.render(),从而引发递归,造成栈溢出
if (renderer.bloomComposer && renderer.finalComposer) {
// 复制需要晕光的纹理涂层
this.object3D.traverse(this.darkenNonBloomed);
renderer.bloomComposer.render();
this.object3D.traverse(this.restoreMaterial);
// 晕光纹理和原图合并渲染
renderer.finalComposer.render();
} else {
renderer.render(this.object3D, this.camera);
}
// 马少杰兼容添加--结束
// 马少杰修改前原版代码
// renderer.render(this.object3D, this.camera);
2、在自己项目中声明你自己需要的Composer,挂载到renderer对象
_ 强烈呼吁:希望Aframe官网能开一个回调,能够重构renderer.render()地方的执行代码,这样我们就可以在不修改Aframe源码的基础上支持各种threejs的Composer引用了 _
关键的副作用-注意:此方案的引入致使renderer的onBeforeRender和onAfterRender这两个钩子函数已不可再使用,因为bloomComposer和finalComposer的render()都会默认调用renderer.render(),从而引发递归,造成栈溢出
如有码友有类似问题需要解决,可以详询我:wechat/QQ:1215458034
Post processing still depends on pending THREE work mrdoob/three.js#18846