mirror of
https://github.com/troisjs/trois.git
synced 2024-11-23 20:02:32 +08:00
wip: effects
This commit is contained in:
parent
1da2a90c67
commit
81852fee78
@ -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',
|
||||
});
|
42
src/effects/BokehPass.ts
Normal file
42
src/effects/BokehPass.ts
Normal file
@ -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',
|
||||
})
|
@ -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',
|
||||
});
|
59
src/effects/EffectComposer.ts
Normal file
59
src/effects/EffectComposer.ts
Normal file
@ -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',
|
||||
})
|
@ -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',
|
||||
});
|
42
src/effects/EffectPass.ts
Normal file
42
src/effects/EffectPass.ts
Normal file
@ -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',
|
||||
})
|
@ -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',
|
||||
});
|
30
src/effects/FXAAPass.ts
Normal file
30
src/effects/FXAAPass.ts
Normal file
@ -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',
|
||||
})
|
@ -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',
|
||||
});
|
26
src/effects/FilmPass.ts
Normal file
26
src/effects/FilmPass.ts
Normal file
@ -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',
|
||||
})
|
@ -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',
|
||||
});
|
30
src/effects/HalftonePass.ts
Normal file
30
src/effects/HalftonePass.ts
Normal file
@ -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',
|
||||
})
|
@ -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',
|
||||
});
|
||||
})
|
@ -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',
|
||||
});
|
||||
})
|
@ -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',
|
||||
});
|
38
src/effects/SSAOPass.ts
Normal file
38
src/effects/SSAOPass.ts
Normal file
@ -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',
|
||||
})
|
@ -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',
|
||||
});
|
@ -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',
|
||||
});
|
27
src/effects/UnrealBloomPass.ts
Normal file
27
src/effects/UnrealBloomPass.ts
Normal file
@ -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',
|
||||
})
|
@ -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',
|
||||
});
|
22
src/effects/ZoomBlurPass.ts
Normal file
22
src/effects/ZoomBlurPass.ts
Normal file
@ -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',
|
||||
})
|
@ -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';
|
12
src/effects/index.ts
Normal file
12
src/effects/index.ts
Normal file
@ -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'
|
Loading…
Reference in New Issue
Block a user