File

projects/atft/src/lib/renderer/bloom.service.ts

Index

Properties
Methods

Methods

Protected darkenNonBloomed
darkenNonBloomed(obj: any)
Parameters :
Name Type Optional
obj any No
Returns : void
Public init
init(renderer: WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera)
Parameters :
Name Type Optional
renderer WebGLRenderer No
scene THREE.Scene No
camera THREE.Camera No
Returns : void
Public render
render()
Returns : void
Protected restoreMaterial
restoreMaterial(obj: any)
Parameters :
Name Type Optional
obj any No
Returns : void

Properties

Private bloomComposer
Type : EffectComposer
Protected bloomLayer
Default value : new THREE.Layers()
Protected darkMaterial
Default value : new THREE.MeshBasicMaterial({color: 'black'})
Private finalComposer
Type : EffectComposer
Public initialized
Default value : false
Protected materials
Type : Array<THREE.Material>
Default value : []
Protected scene
Type : THREE.Scene
import {Injectable} from '@angular/core';
import * as THREE from 'three';
import {WebGLRenderer} from 'three';
import {RenderPass} from 'three/examples/jsm/postprocessing/RenderPass';
import {UnrealBloomPass} from 'three/examples/jsm/postprocessing/UnrealBloomPass';
import {EffectComposer} from 'three/examples/jsm/postprocessing/EffectComposer';
import {ShaderPass} from 'three/examples/jsm/postprocessing/ShaderPass';
import {FXAAShader} from 'three/examples/jsm/shaders/FXAAShader';


export const ENTIRE_SCENE_LAYER = 0, BLOOM_SCENE_LAYER = 1;

const vertexShader = `
  varying vec2 vUv;
  void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  }`;


const fragmentShader = `
  uniform sampler2D baseTexture;
  uniform sampler2D bloomTexture;
  varying vec2 vUv;
  void main() {
    gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );
  }`;


@Injectable()
export class BloomService {

  protected materials: Array<THREE.Material> = [];
  protected darkMaterial = new THREE.MeshBasicMaterial({color: 'black'});
  protected bloomLayer = new THREE.Layers();
  private finalComposer!: EffectComposer;
  private bloomComposer!: EffectComposer;
  public initialized = false;
  protected scene!: THREE.Scene;

  public init(renderer: WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera) {
    if (renderer && scene && camera) {
      // console.log('BloomService.init');
      this.scene = scene;

      this.bloomLayer.set(BLOOM_SCENE_LAYER);
      const renderScene = new RenderPass(scene, camera);

      const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 2, 0.1, 0.1);
      bloomPass.clear = true;

      const fxaaPass = new ShaderPass(FXAAShader);
      const pixelRatio = renderer.getPixelRatio();
      fxaaPass.material.uniforms['resolution'].value.x = 1 / (window.innerWidth * pixelRatio);
      fxaaPass.material.uniforms['resolution'].value.y = 1 / (window.innerHeight * pixelRatio);

      this.bloomComposer = new EffectComposer(renderer);
      this.bloomComposer.renderToScreen = false; // TODO: false
      this.bloomComposer.addPass(renderScene);
      this.bloomComposer.addPass(bloomPass);
      // this.bloomComposer.addPass(fxaaPass);


      const finalPass = new ShaderPass(
        new THREE.ShaderMaterial({
          uniforms: {
            baseTexture: {value: null},
            bloomTexture: {value: this.bloomComposer.renderTarget2.texture}
          },
          vertexShader: vertexShader,
          fragmentShader: fragmentShader,
          defines: {}
        }), 'baseTexture'
      );
      finalPass.needsSwap = true;

      // const smaaPass = new SMAAPass(window.innerWidth, window.innerHeight);

      this.finalComposer = new EffectComposer(renderer);
      this.finalComposer.addPass(renderScene);
      this.finalComposer.addPass(finalPass);
      this.finalComposer.addPass(fxaaPass);
      // this.finalComposer.addPass(smaaPass);


      this.initialized = true;

    } else {
      console.warn('BloomService.init not all parameters settled');
    }
  }

  public render() {
    if (this.initialized) {
      this.scene.traverse(i => {
        this.darkenNonBloomed(i);
      });
      this.bloomComposer.render();


      this.scene.traverse(i => {
        this.restoreMaterial(i);
      });
      this.finalComposer.render();
    }
  }


  protected darkenNonBloomed(obj : any): void {
    if (this.initialized && obj.isMesh && this.bloomLayer.test(obj.layers) === false) {
      // console.log('darkenNonBloomed');
      // @ts-ignore
      this.materials[obj.uuid] = obj.material;
      obj.material = this.darkMaterial;

    }
  }

  protected restoreMaterial(obj : any): void {
    if (this.initialized && obj.isMesh && this.materials[obj.uuid]) {
      obj.material = this.materials[obj.uuid];
      delete this.materials[obj.uuid];
    }
  }

}

results matching ""

    No results matching ""