import { WebGLRenderTarget , Vector2 , Shader , ShaderMaterial , WebGLRenderer , PerspectiveCamera , DepthTexture } from 'three' ; import { FullScreenQuad } from 'three/examples/jsm/postprocessing/Pass' ; import { BlendShader } from 'three/examples/jsm/shaders/BlendShader' ; import { GaussianBlurShader , GaussianBlurDirection } from './shaders/effect/gaussian-blur-shader' ; import { RGBShiftShader } from 'three/examples/jsm/shaders/RGBShiftShader' ; import { VignetteShader } from 'three/examples/jsm/shaders/VignetteShader' ; import { VignetteBlendShader } from './shaders/effect/vignette-blend-shader' ; import { MotionBlurShader } from './shaders/effect/motion-blur-shader' ; import { GlitchShader } from './shaders/transition/glitch-shader' ; import { ShaderUtils , Uniforms } from './shaders/shader-utils' ; enum EffectType { Blur = 'Blur' , Bloom = 'Bloom' , RgbShift = 'RgbShift' , Vignette = 'Vignette' , VignetteBlur = 'VignetteBlur' , MotionBlur = 'MotionBlur' , Glitch = 'Glitch' } interface IEffect { render ( ... args ) ; setSize ? ( width , height ) ; getUniforms ( ) : Uniforms ; updateUniforms ( uniforms ) ; clearUniforms ( ) ; dispose ( ) ; } class Effect implements IEffect { protected _quad : FullScreenQuad = new FullScreenQuad ( ) ; param { Shader } shader param { Uniforms } uniforms constructor ( shader , uniforms = { } ) { this . _quad . material = ShaderUtils . createShaderMaterial ( shader , uniforms ) ; } returns getUniforms ( ) { return ShaderUtils . getUniforms ( this . _quad . material as ShaderMaterial ) ; } param { Uniforms } uniforms updateUniforms ( uniforms = { } ) { ShaderUtils . updateUniforms ( this . _quad . material as ShaderMaterial , uniforms ) ; } /**
     * Resets the uniforms for the effect back to its default values.
     */ clearUniforms ( ) { ShaderUtils . clearUniforms ( this . _quad . material as ShaderMaterial ) ; } param { WebGLRenderer } renderer param { WebGLRenderTarget | null } writeBuffer param { WebGLRenderTarget } readBuffer param { Uniforms } uniforms render ( renderer , writeBuffer , readBuffer , uniforms = { } ) { renderer . setRenderTarget ( writeBuffer ) ; this . updateUniforms ( { ... uniforms , tDiffuse : readBuffer . texture , } ) ; this . _quad . render ( renderer ) ; } /**
     * Disposes this object. Call when this object is no longer needed, otherwise leaks may occur.
     */ dispose ( ) { this . _quad . material . dispose ( ) ; } } class TransitionEffect extends Effect { param { WebGLRenderer } renderer param { WebGLRenderTarget | null } writeBuffer param { WebGLRenderTarget } fromBuffer param { WebGLRenderTarget } toBuffer param { Uniforms } uniforms render ( renderer , writeBuffer , fromBuffer , toBuffer , uniforms = { } ) { renderer . setRenderTarget ( writeBuffer ) ; this . updateUniforms ( { ... uniforms , tDiffuse1 : fromBuffer . texture , tDiffuse2 : toBuffer . texture , } ) ; this . _quad . render ( renderer ) ; } } class MotionBlurEffect extends Effect { camera : PerspectiveCamera ; depthTexture : DepthTexture ; param { PerspectiveCamera } camera param { DepthTexture } depthTexture param { Uniforms } uniforms constructor ( camera , depthTexture , uniforms = { } ) { super ( MotionBlurShader , uniforms ) ; this . camera = camera ; this . depthTexture = depthTexture ; } param { WebGLRenderer } renderer param { WebGLRenderTarget | null } writeBuffer param { WebGLRenderTarget } readBuffer param { Uniforms } uniforms render ( renderer , writeBuffer , readBuffer , uniforms = { } ) { const { clipToWorldMatrix , prevWorldToClipMatrix } = this . getUniforms ( ) ; super . render ( renderer , writeBuffer , readBuffer , { ... uniforms , tDepth : this . depthTexture , clipToWorldMatrix : clipToWorldMatrix . copy ( this . camera . projectionMatrixInverse ) . multiply ( this . camera . matrixWorld ) , } ) ; prevWorldToClipMatrix . copy ( this . camera . matrixWorldInverse ) . multiply ( this . camera . projectionMatrix ) ; } } class GaussianBlurEffect extends Effect { private _width : number ; private _height : number ; private _buffer : WebGLRenderTarget ; passes = 1 ; param { number } width param { number } height param { Uniforms } uniforms constructor ( width , height , uniforms = { } ) { super ( GaussianBlurShader , uniforms ) ; this . _width = width ; this . _height = height ; this . _buffer = new WebGLRenderTarget ( width , height ) ; } param { number } width param { number } height setSize ( width , height ) { this . _width = width ; this . _height = height ; this . _buffer . setSize ( width , height ) ; } param { WebGLRenderer } renderer param { WebGLRenderTarget } writeBuffer param { WebGLRenderTarget } readBuffer param { Uniforms } uniforms render ( renderer , writeBuffer , readBuffer , uniforms = { } ) { for ( let i = 0 ; i < this . passes ; ++ i ) { super . render ( renderer , this . _buffer , i === 0 ? readBuffer : writeBuffer , { ... uniforms , direction : GaussianBlurDirection . HORIZONTAL , resolution : this . _width , } ) ; super . render ( renderer , writeBuffer , this . _buffer , { ... uniforms , direction : GaussianBlurDirection . VERTICAL , resolution : this . _height , } ) ; } } /**
     * Disposes this object. Call when this object is no longer needed, otherwise leaks may occur.
     */ dispose ( ) { this . _buffer . dispose ( ) ; super . dispose ( ) ; } } class BloomEffect implements IEffect { private _blurEffect : GaussianBlurEffect ; private _blendEffect : TransitionEffect ; private _blendBuffer : WebGLRenderTarget ; param { number } width param { number } height param { Uniforms } uniforms constructor ( width , height , uniforms = { } ) { this . _blurEffect = new GaussianBlurEffect ( width , height ) ; this . _blendEffect = new TransitionEffect ( BlendShader , { mixRatio : 0.5 } ) ; this . _blendBuffer = new WebGLRenderTarget ( width , height ) ; this . updateUniforms ( uniforms ) ; } returns get passes ( ) : number { return this . _blurEffect . passes ; } param { number } value set passes ( value ) { this . _blurEffect . passes = value ; } param { number } width param { number } height setSize ( width , height ) { this . _blurEffect . setSize ( width , height ) ; this . _blendBuffer . setSize ( width , height ) ; } returns getUniforms ( ) { const { opacity } = this . _blendEffect . getUniforms ( ) ; return { ... this . _blurEffect . getUniforms ( ) , opacity } ; } param { Uniforms } uniforms updateUniforms ( uniforms = { } ) { const blendUniforms = this . _blendEffect . getUniforms ( ) ; const { opacity = blendUniforms . opacity , ... blurUniforms } = uniforms ; this . _blurEffect . updateUniforms ( blurUniforms ) ; this . _blendEffect . updateUniforms ( { opacity } ) ; } /**
     * Resets the uniforms for the effect back to its default values.
     */ clearUniforms ( ) { this . _blurEffect . clearUniforms ( ) ; this . _blendEffect . clearUniforms ( ) ; this . _blendEffect . updateUniforms ( { mixRatio : 0.5 } ) ; } param { WebGLRenderer } renderer param { WebGLRenderTarget | null } writeBuffer param { WebGLRenderTarget } readBuffer param { Uniforms } uniforms render ( renderer , writeBuffer , readBuffer , uniforms = { } ) { this . _blurEffect . render ( renderer , this . _blendBuffer , readBuffer , uniforms ) ; this . _blendEffect . render ( renderer , writeBuffer , readBuffer , this . _blendBuffer ) ; } /**
     * Disposes this object. Call when this object is no longer needed, otherwise leaks may occur.
     */ dispose ( ) { this . _blendEffect . dispose ( ) ; this . _blendBuffer . dispose ( ) ; } } class RGBShiftEffect extends Effect { param { Uniforms } uniforms constructor ( uniforms = { } ) { super ( RGBShiftShader , uniforms ) ; } } class VignetteEffect extends Effect { param { Uniforms } uniforms constructor ( uniforms = { } ) { super ( VignetteShader , uniforms ) ; } } class VignetteBlurEffect implements IEffect { private _blurEffect : GaussianBlurEffect ; private _blendEffect : TransitionEffect ; private _blendBuffer : WebGLRenderTarget ; param { number } width param { number } height param { Uniforms } uniforms constructor ( width , height , uniforms = { } ) { this . _blurEffect = new GaussianBlurEffect ( width , height ) ; this . _blendEffect = new TransitionEffect ( VignetteBlendShader ) ; this . _blendBuffer = new WebGLRenderTarget ( width , height ) ; this . updateUniforms ( uniforms ) ; } returns get passes ( ) : number { return this . _blurEffect . passes ; } param { number } value set passes ( value ) { this . _blurEffect . passes = value ; } param { number } width param { number } height setSize ( width , height ) { this . _blurEffect . setSize ( width , height ) ; this . _blendBuffer . setSize ( width , height ) ; } returns getUniforms ( ) { const { size } = this . _blendEffect . getUniforms ( ) ; return { ... this . _blurEffect . getUniforms ( ) , size } ; } param { Uniforms } uniforms updateUniforms ( uniforms = { } ) { const blendUniforms = this . _blendEffect . getUniforms ( ) ; const { size = blendUniforms . size , ... blurUniforms } = uniforms ; this . _blurEffect . updateUniforms ( blurUniforms ) ; this . _blendEffect . updateUniforms ( { size } ) ; } /**
     * Resets the uniforms for the effect back to its default values.
     */ clearUniforms ( ) { this . _blurEffect . clearUniforms ( ) ; this . _blendEffect . clearUniforms ( ) ; } param { WebGLRenderer } renderer param { WebGLRenderTarget | null } writeBuffer param { WebGLRenderTarget } readBuffer param { Uniforms } uniforms render ( renderer , writeBuffer , readBuffer , uniforms = { } ) { this . _blurEffect . render ( renderer , this . _blendBuffer , readBuffer , uniforms ) ; this . _blendEffect . render ( renderer , writeBuffer , readBuffer , this . _blendBuffer ) ; } /**
     * Disposes this object. Call when this object is no longer needed, otherwise leaks may occur.
     */ dispose ( ) { this . _blurEffect . dispose ( ) ; this . _blendEffect . dispose ( ) ; this . _blendBuffer . dispose ( ) ; } } class GlitchEffect implements IEffect { private _resolution : Vector2 ; private _glitchEffect : TransitionEffect ; private _blurEffect : GaussianBlurEffect ; private _blurBuffer : WebGLRenderTarget ; param { number } width param { number } height param { Uniforms } uniforms constructor ( width , height , uniforms = { } ) { this . _resolution = new Vector2 ( width , height ) ; this . _glitchEffect = new TransitionEffect ( GlitchShader ) ; this . _blurEffect = new GaussianBlurEffect ( width , height , { radius : 3 } ) ; this . _blurEffect . passes = 2 ; this . _blurBuffer = new WebGLRenderTarget ( width , height ) ; this . updateUniforms ( uniforms ) ; } param { number } width param { number } height setSize ( width , height ) { this . _resolution . set ( width , height ) ; this . _blurEffect . setSize ( width , height ) ; this . _blurBuffer . setSize ( width , height ) ; } returns getUniforms ( ) { return this . _glitchEffect . getUniforms ( ) ; } param { Uniforms } uniforms updateUniforms ( uniforms = { } ) { this . _glitchEffect . updateUniforms ( uniforms ) ; } /**
     * Resets the uniforms for the effect back to its default values.
     */ clearUniforms ( ) { this . _glitchEffect . clearUniforms ( ) ; } param { WebGLRenderer } renderer param { WebGLRenderTarget | null } writeBuffer param { WebGLRenderTarget } readBuffer param { Uniforms } uniforms render ( renderer , writeBuffer , readBuffer , uniforms = { } ) { this . _blurEffect . render ( renderer , this . _blurBuffer , readBuffer ) ; this . _glitchEffect . render ( renderer , writeBuffer , readBuffer , this . _blurBuffer , { ... uniforms , resolution : this . _resolution , } ) ; } /**
     * Disposes this object. Call when this object is no longer needed, otherwise leaks may occur.
     */ dispose ( ) { this . _glitchEffect . dispose ( ) ; this . _blurEffect . dispose ( ) ; this . _blurBuffer . dispose ( ) ; } } export { EffectType , IEffect , Effect , TransitionEffect , GaussianBlurEffect , BloomEffect , RGBShiftEffect , VignetteEffect , VignetteBlurEffect , MotionBlurEffect , GlitchEffect , } ;