Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to use EffectComposer/UnrealBloomPass in Aframe #4897

Closed
JetsomMa opened this issue Jul 31, 2021 · 4 comments
Closed

how to use EffectComposer/UnrealBloomPass in Aframe #4897

JetsomMa opened this issue Jul 31, 2021 · 4 comments

Comments

@JetsomMa
Copy link

JetsomMa commented Jul 31, 2021

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:
@JetsomMa
Copy link
Author

JetsomMa commented Aug 5, 2021

英语不太好,我就直接写中文了,

以上问题我已经解决,希望对有需要的人有帮助

经过多天研读源码,加上看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

@dmarcos
Copy link
Member

dmarcos commented Aug 9, 2021

Post processing still depends on pending THREE work mrdoob/three.js#18846

@vincentfretin
Copy link
Contributor

We have an example of using UnrealBloomPass in #5648

@dmarcos
Copy link
Member

dmarcos commented Feb 14, 2025

Closing this. Can reopen if necessary

@dmarcos dmarcos closed this as completed Feb 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants