From 81852fee786bd3b6741a4e6fb719f932a9235bdc Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Tue, 20 Apr 2021 12:41:04 +0200 Subject: [PATCH] wip: effects --- src/effects/BokehPass.js | 44 --------------- src/effects/BokehPass.ts | 42 ++++++++++++++ src/effects/EffectComposer.js | 41 -------------- src/effects/EffectComposer.ts | 59 ++++++++++++++++++++ src/effects/EffectPass.js | 25 --------- src/effects/EffectPass.ts | 42 ++++++++++++++ src/effects/FXAAPass.js | 26 --------- src/effects/FXAAPass.ts | 30 ++++++++++ src/effects/FilmPass.js | 24 -------- src/effects/FilmPass.ts | 26 +++++++++ src/effects/HalftonePass.js | 28 ---------- src/effects/HalftonePass.ts | 30 ++++++++++ src/effects/{RenderPass.js => RenderPass.ts} | 20 ++++--- src/effects/{SMAAPass.js => SMAAPass.ts} | 14 ++--- src/effects/SSAOPass.js | 30 ---------- src/effects/SSAOPass.ts | 38 +++++++++++++ src/effects/TiltShiftPass.js | 57 ------------------- src/effects/UnrealBloomPass.js | 24 -------- src/effects/UnrealBloomPass.ts | 27 +++++++++ src/effects/ZoomBlurPass.js | 23 -------- src/effects/ZoomBlurPass.ts | 22 ++++++++ src/effects/index.js | 12 ---- src/effects/index.ts | 12 ++++ 23 files changed, 346 insertions(+), 350 deletions(-) delete mode 100644 src/effects/BokehPass.js create mode 100644 src/effects/BokehPass.ts delete mode 100644 src/effects/EffectComposer.js create mode 100644 src/effects/EffectComposer.ts delete mode 100644 src/effects/EffectPass.js create mode 100644 src/effects/EffectPass.ts delete mode 100644 src/effects/FXAAPass.js create mode 100644 src/effects/FXAAPass.ts delete mode 100644 src/effects/FilmPass.js create mode 100644 src/effects/FilmPass.ts delete mode 100644 src/effects/HalftonePass.js create mode 100644 src/effects/HalftonePass.ts rename src/effects/{RenderPass.js => RenderPass.ts} (54%) rename src/effects/{SMAAPass.js => SMAAPass.ts} (66%) delete mode 100644 src/effects/SSAOPass.js create mode 100644 src/effects/SSAOPass.ts delete mode 100644 src/effects/TiltShiftPass.js delete mode 100644 src/effects/UnrealBloomPass.js create mode 100644 src/effects/UnrealBloomPass.ts delete mode 100644 src/effects/ZoomBlurPass.js create mode 100644 src/effects/ZoomBlurPass.ts delete mode 100644 src/effects/index.js create mode 100644 src/effects/index.ts diff --git a/src/effects/BokehPass.js b/src/effects/BokehPass.js deleted file mode 100644 index 616c1ae..0000000 --- a/src/effects/BokehPass.js +++ /dev/null @@ -1,44 +0,0 @@ -import { defineComponent } from 'vue'; -import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass.js'; -import EffectPass from './EffectPass.js'; - -export default defineComponent({ - extends: EffectPass, - props: { - focus: { - type: Number, - default: 1, - }, - aperture: { - type: Number, - default: 0.025, - }, - maxblur: { - type: Number, - default: 0.01, - }, - }, - watch: { - focus() { this.pass.uniforms.focus.value = this.focus; }, - aperture() { this.pass.uniforms.aperture.value = this.aperture; }, - maxblur() { this.pass.uniforms.maxblur.value = this.maxblur; }, - }, - mounted() { - if (!this.three.scene) { - console.error('Missing Scene'); - } - if (!this.three.camera) { - console.error('Missing Camera'); - } - const params = { - focus: this.focus, - aperture: this.aperture, - maxblur: this.maxblur, - width: this.three.size.width, - height: this.three.size.height, - }; - const pass = new BokehPass(this.three.scene, this.three.camera, params); - this.completePass(pass); - }, - __hmrId: 'BokehPass', -}); diff --git a/src/effects/BokehPass.ts b/src/effects/BokehPass.ts new file mode 100644 index 0000000..4078a3e --- /dev/null +++ b/src/effects/BokehPass.ts @@ -0,0 +1,42 @@ +import { defineComponent, watch } from 'vue' +import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass.js' +import EffectPass from './EffectPass' + +const props = { + focus: { type: Number, default: 1 }, + aperture: { type: Number, default: 0.025 }, + maxblur: { type: Number, default: 0.01 }, +} + +export default defineComponent({ + extends: EffectPass, + props, + created() { + if (!this.three.scene) { + console.error('Missing Scene') + return + } + if (!this.three.camera) { + console.error('Missing Camera') + return + } + + const params = { + focus: this.focus, + aperture: this.aperture, + maxblur: this.maxblur, + width: this.three.size.width, + height: this.three.size.height, + } + + const pass = new BokehPass(this.three.scene, this.three.camera, params) + + Object.keys(props).forEach(p => { + // @ts-ignore + watch(() => this[p], (value) => { pass.uniforms[p].value = value }) + }) + + this.initEffectPass(pass) + }, + __hmrId: 'BokehPass', +}) diff --git a/src/effects/EffectComposer.js b/src/effects/EffectComposer.js deleted file mode 100644 index 195d08c..0000000 --- a/src/effects/EffectComposer.js +++ /dev/null @@ -1,41 +0,0 @@ -import { defineComponent } from 'vue'; -import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'; - -export default defineComponent({ - setup() { - return { - passes: [], - }; - }, - inject: ['three'], - provide() { - return { - passes: this.passes, - }; - }, - mounted() { - this.three.onAfterInit(() => { - this.composer = new EffectComposer(this.three.renderer); - this.three.renderer.autoClear = false; - this.passes.forEach(pass => { - this.composer.addPass(pass); - }); - this.three.composer = this.composer; - - this.resize(); - this.three.onAfterResize(this.resize); - }); - }, - unmounted() { - this.three.offAfterResize(this.resize); - }, - methods: { - resize() { - this.composer.setSize(this.three.size.width, this.three.size.height); - }, - }, - render() { - return this.$slots.default(); - }, - __hmrId: 'EffectComposer', -}); diff --git a/src/effects/EffectComposer.ts b/src/effects/EffectComposer.ts new file mode 100644 index 0000000..acd2f53 --- /dev/null +++ b/src/effects/EffectComposer.ts @@ -0,0 +1,59 @@ +import { defineComponent, inject } from 'vue' +import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js' +import { ThreeInterface } from '../core/useThree' +import { Pass } from 'three/examples/jsm/postprocessing/Pass' + +interface EffectComposerSetupInterface { + three: ThreeInterface + // passes: Pass[] + composer?: EffectComposer +} + +export interface EffectComposerInterface extends EffectComposerSetupInterface { + addPass(pass: Pass): void + removePass(pass: Pass): void +} + +export default defineComponent({ + setup(): EffectComposerSetupInterface { + const three = inject('three') as ThreeInterface + return { + three, + // passes: [], + } + }, + provide() { + return { + composer: this, + } + }, + created() { + const composer = new EffectComposer(this.three.renderer) + this.composer = composer + this.three.composer = composer + + this.three.onAfterInit(() => { + this.three.renderer.autoClear = false + this.resize() + this.three.onAfterResize(this.resize) + }) + }, + unmounted() { + this.three.offAfterResize(this.resize) + }, + methods: { + addPass(pass: Pass) { + this.composer?.addPass(pass) + }, + removePass(pass: Pass) { + this.composer?.removePass(pass) + }, + resize() { + this.composer?.setSize(this.three.size.width, this.three.size.height) + }, + }, + render() { + return this.$slots.default ? this.$slots.default() : [] + }, + __hmrId: 'EffectComposer', +}) diff --git a/src/effects/EffectPass.js b/src/effects/EffectPass.js deleted file mode 100644 index 4cf08e0..0000000 --- a/src/effects/EffectPass.js +++ /dev/null @@ -1,25 +0,0 @@ -import { defineComponent } from 'vue'; - -export default defineComponent({ - inject: ['three', 'passes'], - emits: ['ready'], - beforeMount() { - if (!this.passes) { - console.error('Missing parent EffectComposer'); - } - }, - unmounted() { - if (this.pass.dispose) this.pass.dispose(); - }, - methods: { - completePass(pass) { - this.passes.push(pass); - this.pass = pass; - this.$emit('ready', pass); - }, - }, - render() { - return []; - }, - __hmrId: 'EffectPass', -}); diff --git a/src/effects/EffectPass.ts b/src/effects/EffectPass.ts new file mode 100644 index 0000000..948c7f1 --- /dev/null +++ b/src/effects/EffectPass.ts @@ -0,0 +1,42 @@ +import { Pass } from 'three/examples/jsm/postprocessing/Pass' +import { defineComponent, inject } from 'vue' +import { ThreeInterface } from '../core/useThree' +import { EffectComposerInterface } from './EffectComposer' + +interface EffectSetupInterface { + three: ThreeInterface + composer: EffectComposerInterface + pass?: Pass +} + +export default defineComponent({ + inject: ['three', 'composer'], + emits: ['ready'], + setup(): EffectSetupInterface { + const three = inject('three') as ThreeInterface + const composer = inject('composer') as EffectComposerInterface + return { three, composer } + }, + created() { + if (!this.composer) { + console.error('Missing parent EffectComposer') + } + }, + unmounted() { + if (this.pass) { + this.composer.removePass(this.pass); + (this.pass as any).dispose?.() + } + }, + methods: { + initEffectPass(pass: Pass) { + this.pass = pass + this.composer.addPass(pass) + this.$emit('ready', pass) + }, + }, + render() { + return [] + }, + __hmrId: 'EffectPass', +}) diff --git a/src/effects/FXAAPass.js b/src/effects/FXAAPass.js deleted file mode 100644 index b48078b..0000000 --- a/src/effects/FXAAPass.js +++ /dev/null @@ -1,26 +0,0 @@ -import { defineComponent } from 'vue'; -import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; -import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'; -import EffectPass from './EffectPass.js'; - -export default defineComponent({ - extends: EffectPass, - mounted() { - const pass = new ShaderPass(FXAAShader); - this.completePass(pass); - - // resize will be called in three init - this.three.onAfterResize(this.resize); - }, - unmounted() { - this.three.offAfterResize(this.resize); - }, - methods: { - resize() { - const { resolution } = this.pass.material.uniforms; - resolution.value.x = 1 / this.three.size.width; - resolution.value.y = 1 / this.three.size.height; - }, - }, - __hmrId: 'FXAAPass', -}); diff --git a/src/effects/FXAAPass.ts b/src/effects/FXAAPass.ts new file mode 100644 index 0000000..fafa847 --- /dev/null +++ b/src/effects/FXAAPass.ts @@ -0,0 +1,30 @@ +import { defineComponent } from 'vue' +import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js' +import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js' +import EffectPass from './EffectPass' +import { ThreeResizeEventInterface } from '../core/useThree' + +export default defineComponent({ + extends: EffectPass, + created() { + const pass = new ShaderPass(FXAAShader) + + // resize will be called in three init + this.three.onAfterResize(this.resize) + + this.initEffectPass(pass) + }, + unmounted() { + this.three.offAfterResize(this.resize) + }, + methods: { + resize({ size }: ThreeResizeEventInterface) { + if (this.pass) { + const { resolution } = (this.pass as ShaderPass).material.uniforms + resolution.value.x = 1 / size.width + resolution.value.y = 1 / size.height + } + }, + }, + __hmrId: 'FXAAPass', +}) diff --git a/src/effects/FilmPass.js b/src/effects/FilmPass.js deleted file mode 100644 index ab055a9..0000000 --- a/src/effects/FilmPass.js +++ /dev/null @@ -1,24 +0,0 @@ -import { defineComponent } from 'vue'; -import { FilmPass } from 'three/examples/jsm/postprocessing/FilmPass.js'; -import EffectPass from './EffectPass.js'; - -export default defineComponent({ - extends: EffectPass, - props: { - noiseIntensity: { type: Number, default: 0.5 }, - scanlinesIntensity: { type: Number, default: 0.05 }, - scanlinesCount: { type: Number, default: 4096 }, - grayscale: { type: Number, default: 0 }, - }, - watch: { - noiseIntensity() { this.pass.uniforms.nIntensity.value = this.noiseIntensity; }, - scanlinesIntensity() { this.pass.uniforms.sIntensity.value = this.scanlinesIntensity; }, - scanlinesCount() { this.pass.uniforms.sCount.value = this.scanlinesCount; }, - grayscale() { this.pass.uniforms.grayscale.value = this.grayscale; }, - }, - mounted() { - const pass = new FilmPass(this.noiseIntensity, this.scanlinesIntensity, this.scanlinesCount, this.grayscale); - this.completePass(pass); - }, - __hmrId: 'FilmPass', -}); diff --git a/src/effects/FilmPass.ts b/src/effects/FilmPass.ts new file mode 100644 index 0000000..db21081 --- /dev/null +++ b/src/effects/FilmPass.ts @@ -0,0 +1,26 @@ +import { defineComponent, watch } from 'vue' +import { FilmPass } from 'three/examples/jsm/postprocessing/FilmPass.js' +import EffectPass from './EffectPass' + +const props = { + noiseIntensity: { type: Number, default: 0.5 }, + scanlinesIntensity: { type: Number, default: 0.05 }, + scanlinesCount: { type: Number, default: 4096 }, + grayscale: { type: Number, default: 0 }, +} + +export default defineComponent({ + extends: EffectPass, + props, + created() { + const pass = new FilmPass(this.noiseIntensity, this.scanlinesIntensity, this.scanlinesCount, this.grayscale) + + Object.keys(props).forEach(p => { + // @ts-ignore + watch(() => this[p], (value) => { pass.uniforms[p].value = value }) + }) + + this.initEffectPass(pass) + }, + __hmrId: 'FilmPass', +}) diff --git a/src/effects/HalftonePass.js b/src/effects/HalftonePass.js deleted file mode 100644 index fc893c6..0000000 --- a/src/effects/HalftonePass.js +++ /dev/null @@ -1,28 +0,0 @@ -import { defineComponent, watch } from 'vue'; -import { HalftonePass } from 'three/examples/jsm/postprocessing/HalftonePass.js'; -import EffectPass from './EffectPass.js'; - -export default defineComponent({ - extends: EffectPass, - props: { - shape: { type: Number, default: 1 }, - radius: { type: Number, default: 4 }, - rotateR: { type: Number, default: Math.PI / 12 * 1 }, - rotateG: { type: Number, default: Math.PI / 12 * 2 }, - rotateB: { type: Number, default: Math.PI / 12 * 3 }, - scatter: { type: Number, default: 0 }, - }, - mounted() { - const pass = new HalftonePass(this.three.size.width, this.three.size.height, {}); - - ['shape', 'radius', 'rotateR', 'rotateG', 'rotateB', 'scatter'].forEach(p => { - pass.uniforms[p].value = this[p]; - watch(() => this[p], () => { - pass.uniforms[p].value = this[p]; - }); - }); - - this.completePass(pass); - }, - __hmrId: 'HalftonePass', -}); diff --git a/src/effects/HalftonePass.ts b/src/effects/HalftonePass.ts new file mode 100644 index 0000000..de15349 --- /dev/null +++ b/src/effects/HalftonePass.ts @@ -0,0 +1,30 @@ +import { defineComponent, watch } from 'vue' +import { HalftonePass } from 'three/examples/jsm/postprocessing/HalftonePass.js' +import EffectPass from './EffectPass' + +const props = { + shape: { type: Number, default: 1 }, + radius: { type: Number, default: 4 }, + rotateR: { type: Number, default: Math.PI / 12 * 1 }, + rotateG: { type: Number, default: Math.PI / 12 * 2 }, + rotateB: { type: Number, default: Math.PI / 12 * 3 }, + scatter: { type: Number, default: 0 }, +} + +export default defineComponent({ + extends: EffectPass, + props, + created() { + const pass = new HalftonePass(this.three.size.width, this.three.size.height, {}) + + Object.keys(props).forEach(p => { + // @ts-ignore + pass.uniforms[p].value = this[p] + // @ts-ignore + watch(() => this[p], (value) => { pass.uniforms[p].value = value }) + }) + + this.initEffectPass(pass) + }, + __hmrId: 'HalftonePass', +}) diff --git a/src/effects/RenderPass.js b/src/effects/RenderPass.ts similarity index 54% rename from src/effects/RenderPass.js rename to src/effects/RenderPass.ts index a3a45f5..52a3e94 100644 --- a/src/effects/RenderPass.js +++ b/src/effects/RenderPass.ts @@ -1,18 +1,20 @@ -import { defineComponent } from 'vue'; -import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'; -import EffectPass from './EffectPass.js'; +import { defineComponent } from 'vue' +import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js' +import EffectPass from './EffectPass' export default defineComponent({ extends: EffectPass, - mounted() { + created() { if (!this.three.scene) { - console.error('Missing Scene'); + console.error('Missing Scene') + return } if (!this.three.camera) { - console.error('Missing Camera'); + console.error('Missing Camera') + return } - const pass = new RenderPass(this.three.scene, this.three.camera); - this.completePass(pass); + const pass = new RenderPass(this.three.scene, this.three.camera) + this.initEffectPass(pass) }, __hmrId: 'RenderPass', -}); +}) diff --git a/src/effects/SMAAPass.js b/src/effects/SMAAPass.ts similarity index 66% rename from src/effects/SMAAPass.js rename to src/effects/SMAAPass.ts index 4d45a21..7599fcb 100644 --- a/src/effects/SMAAPass.js +++ b/src/effects/SMAAPass.ts @@ -1,13 +1,13 @@ -import { defineComponent } from 'vue'; -import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass.js'; -import EffectPass from './EffectPass.js'; +import { defineComponent } from 'vue' +import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass.js' +import EffectPass from './EffectPass' export default defineComponent({ extends: EffectPass, - mounted() { + created() { // three size is not set yet, but this pass will be resized by effect composer - const pass = new SMAAPass(this.three.size.width, this.three.size.height); - this.completePass(pass); + const pass = new SMAAPass(this.three.size.width, this.three.size.height) + this.initEffectPass(pass) }, __hmrId: 'SMAAPass', -}); +}) diff --git a/src/effects/SSAOPass.js b/src/effects/SSAOPass.js deleted file mode 100644 index ed6d919..0000000 --- a/src/effects/SSAOPass.js +++ /dev/null @@ -1,30 +0,0 @@ -import { defineComponent } from 'vue'; -import { SSAOPass } from 'three/examples/jsm/postprocessing/SSAOPass.js'; -import EffectPass from './EffectPass.js'; - -export default defineComponent({ - extends: EffectPass, - props: { - scene: null, - camera: null, - options: { - type: Object, - default: () => ({}), - }, - }, - mounted() { - const pass = new SSAOPass( - this.scene || this.three.scene, - this.camera || this.three.camera, - this.three.size.width, - this.three.size.height - ); - - for (const key of Object.keys(this.options)) { - pass[key] = this.options[key]; - } - - this.completePass(pass); - }, - __hmrId: 'SSAOPass', -}); diff --git a/src/effects/SSAOPass.ts b/src/effects/SSAOPass.ts new file mode 100644 index 0000000..bae76db --- /dev/null +++ b/src/effects/SSAOPass.ts @@ -0,0 +1,38 @@ +import { defineComponent } from 'vue' +import { SSAOPass } from 'three/examples/jsm/postprocessing/SSAOPass.js' +import EffectPass from './EffectPass' + +export default defineComponent({ + extends: EffectPass, + props: { + options: { + type: Object, + default: () => ({}), + }, + }, + created() { + if (!this.three.scene) { + console.error('Missing Scene') + return + } + if (!this.three.camera) { + console.error('Missing Camera') + return + } + + const pass = new SSAOPass( + this.three.scene, + this.three.camera, + this.three.size.width, + this.three.size.height + ) + + Object.keys(this.options).forEach(key => { + // @ts-ignore + pass[key] = this.options[key] + }) + + this.initEffectPass(pass) + }, + __hmrId: 'SSAOPass', +}) diff --git a/src/effects/TiltShiftPass.js b/src/effects/TiltShiftPass.js deleted file mode 100644 index 0ec41f3..0000000 --- a/src/effects/TiltShiftPass.js +++ /dev/null @@ -1,57 +0,0 @@ -import { defineComponent, watch } from 'vue'; -import { Vector2 } from 'three'; -import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; -import EffectPass from './EffectPass.js'; -import TiltShift from '../shaders/TiltShift.js'; -import { bindProp } from '../tools'; - -export default defineComponent({ - extends: EffectPass, - props: { - blurRadius: { type: Number, default: 10 }, - gradientRadius: { type: Number, default: 100 }, - start: { type: Object, default: { x: 0, y: 100 } }, - end: { type: Object, default: { x: 10, y: 100 } }, - }, - mounted() { - this.pass = new ShaderPass(TiltShift); - this.passes.push(this.pass); - - this.pass1 = new ShaderPass(TiltShift); - this.passes.push(this.pass1); - - const uniforms = this.uniforms = this.pass.uniforms; - const uniforms1 = this.uniforms1 = this.pass1.uniforms; - uniforms1.blurRadius = uniforms.blurRadius; - uniforms1.gradientRadius = uniforms.gradientRadius; - uniforms1.start = uniforms.start; - uniforms1.end = uniforms.end; - uniforms1.texSize = uniforms.texSize; - - bindProp(this, 'blurRadius', uniforms.blurRadius, 'value'); - bindProp(this, 'gradientRadius', uniforms.gradientRadius, 'value'); - - this.updateFocusLine(); - ['start', 'end'].forEach(p => { - watch(() => this[p], this.updateFocusLine, { deep: true }); - }); - - this.pass.setSize = (width, height) => { - uniforms.texSize.value.set(width, height); - }; - - // emit ready event with two passes - do so manually in this file instead - // of calling `completePass` like in other effect types - this.$emit('ready', [this.pass, this.pass1]); - }, - methods: { - updateFocusLine() { - this.uniforms.start.value.copy(this.start); - this.uniforms.end.value.copy(this.end); - const dv = new Vector2().copy(this.end).sub(this.start).normalize(); - this.uniforms.delta.value.copy(dv); - this.uniforms1.delta.value.set(-dv.y, dv.x); - }, - }, - __hmrId: 'TiltShiftPass', -}); diff --git a/src/effects/UnrealBloomPass.js b/src/effects/UnrealBloomPass.js deleted file mode 100644 index 862df34..0000000 --- a/src/effects/UnrealBloomPass.js +++ /dev/null @@ -1,24 +0,0 @@ -import { defineComponent } from 'vue'; -import { Vector2 } from 'three'; -import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js'; -import EffectPass from './EffectPass.js'; - -export default defineComponent({ - extends: EffectPass, - props: { - strength: { type: Number, default: 1.5 }, - radius: { type: Number, default: 0 }, - threshold: { type: Number, default: 0 }, - }, - watch: { - strength() { this.pass.strength = this.strength; }, - radius() { this.pass.radius = this.radius; }, - threshold() { this.pass.threshold = this.threshold; }, - }, - mounted() { - const size = new Vector2(this.three.size.width, this.three.size.height); - const pass = new UnrealBloomPass(size, this.strength, this.radius, this.threshold); - this.completePass(pass); - }, - __hmrId: 'UnrealBloomPass', -}); diff --git a/src/effects/UnrealBloomPass.ts b/src/effects/UnrealBloomPass.ts new file mode 100644 index 0000000..323d950 --- /dev/null +++ b/src/effects/UnrealBloomPass.ts @@ -0,0 +1,27 @@ +import { defineComponent, watch } from 'vue' +import { Vector2 } from 'three' +import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js' +import EffectPass from './EffectPass' + +const props = { + strength: { type: Number, default: 1.5 }, + radius: { type: Number, default: 0 }, + threshold: { type: Number, default: 0 }, +} + +export default defineComponent({ + extends: EffectPass, + props, + created() { + const size = new Vector2(this.three.size.width, this.three.size.height) + const pass = new UnrealBloomPass(size, this.strength, this.radius, this.threshold) + + Object.keys(props).forEach(p => { + // @ts-ignore + watch(() => this[p], (value) => { pass.uniforms[p].value = value }) + }) + + this.initEffectPass(pass) + }, + __hmrId: 'UnrealBloomPass', +}) diff --git a/src/effects/ZoomBlurPass.js b/src/effects/ZoomBlurPass.js deleted file mode 100644 index 6c8c177..0000000 --- a/src/effects/ZoomBlurPass.js +++ /dev/null @@ -1,23 +0,0 @@ -import { defineComponent } from 'vue'; -import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'; -import EffectPass from './EffectPass.js'; -import ZoomBlur from '../shaders/ZoomBlur.js'; -import { bindProp } from '../tools'; - -export default defineComponent({ - extends: EffectPass, - props: { - center: { type: Object, default: { x: 0.5, y: 0.5 } }, - strength: { type: Number, default: 0.5 }, - }, - mounted() { - const pass = new ShaderPass(ZoomBlur); - - const uniforms = this.uniforms = pass.uniforms; - bindProp(this, 'center', uniforms.center, 'value'); - bindProp(this, 'strength', uniforms.strength, 'value'); - - this.completePass(pass); - }, - __hmrId: 'ZoomBlurPass', -}); diff --git a/src/effects/ZoomBlurPass.ts b/src/effects/ZoomBlurPass.ts new file mode 100644 index 0000000..5cef55c --- /dev/null +++ b/src/effects/ZoomBlurPass.ts @@ -0,0 +1,22 @@ +import { defineComponent } from 'vue' +import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js' +import EffectPass from './EffectPass' +import ZoomBlur from '../shaders/ZoomBlur' +import { bindProp } from '../tools' + +export default defineComponent({ + extends: EffectPass, + props: { + center: { type: Object, default: () => ({ x: 0.5, y: 0.5 }) }, + strength: { type: Number, default: 0.5 }, + }, + created() { + const pass = new ShaderPass(ZoomBlur) + + bindProp(this, 'center', pass.uniforms.center, 'value') + bindProp(this, 'strength', pass.uniforms.strength, 'value') + + this.initEffectPass(pass) + }, + __hmrId: 'ZoomBlurPass', +}) diff --git a/src/effects/index.js b/src/effects/index.js deleted file mode 100644 index 5681b80..0000000 --- a/src/effects/index.js +++ /dev/null @@ -1,12 +0,0 @@ -export { default as EffectComposer } from './EffectComposer.js'; -export { default as RenderPass } from './RenderPass.js'; - -export { default as BokehPass } from './BokehPass.js'; -export { default as FilmPass } from './FilmPass.js'; -export { default as FXAAPass } from './FXAAPass.js'; -export { default as HalftonePass } from './HalftonePass.js'; -export { default as SMAAPass } from './SMAAPass.js'; -export { default as SSAOPass } from './SSAOPass.js'; -export { default as TiltShiftPass } from './TiltShiftPass.js'; -export { default as UnrealBloomPass } from './UnrealBloomPass.js'; -export { default as ZoomBlurPass } from './ZoomBlurPass.js'; diff --git a/src/effects/index.ts b/src/effects/index.ts new file mode 100644 index 0000000..584d323 --- /dev/null +++ b/src/effects/index.ts @@ -0,0 +1,12 @@ +export { default as EffectComposer } from './EffectComposer' +export { default as RenderPass } from './RenderPass' + +export { default as BokehPass } from './BokehPass' +export { default as FilmPass } from './FilmPass' +export { default as FXAAPass } from './FXAAPass' +export { default as HalftonePass } from './HalftonePass' +export { default as SMAAPass } from './SMAAPass' +export { default as SSAOPass } from './SSAOPass' +export { default as TiltShiftPass } from './TiltShiftPass' +export { default as UnrealBloomPass } from './UnrealBloomPass' +export { default as ZoomBlurPass } from './ZoomBlurPass'