mirror of
https://github.com/troisjs/trois.git
synced 2024-11-24 04:12:02 +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 { defineComponent } from 'vue'
|
||||||
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
|
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
|
||||||
import EffectPass from './EffectPass.js';
|
import EffectPass from './EffectPass'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
extends: EffectPass,
|
extends: EffectPass,
|
||||||
mounted() {
|
created() {
|
||||||
if (!this.three.scene) {
|
if (!this.three.scene) {
|
||||||
console.error('Missing Scene');
|
console.error('Missing Scene')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (!this.three.camera) {
|
if (!this.three.camera) {
|
||||||
console.error('Missing Camera');
|
console.error('Missing Camera')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
const pass = new RenderPass(this.three.scene, this.three.camera);
|
const pass = new RenderPass(this.three.scene, this.three.camera)
|
||||||
this.completePass(pass);
|
this.initEffectPass(pass)
|
||||||
},
|
},
|
||||||
__hmrId: 'RenderPass',
|
__hmrId: 'RenderPass',
|
||||||
});
|
})
|
@ -1,13 +1,13 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue'
|
||||||
import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass.js';
|
import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass.js'
|
||||||
import EffectPass from './EffectPass.js';
|
import EffectPass from './EffectPass'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
extends: EffectPass,
|
extends: EffectPass,
|
||||||
mounted() {
|
created() {
|
||||||
// three size is not set yet, but this pass will be resized by effect composer
|
// 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);
|
const pass = new SMAAPass(this.three.size.width, this.three.size.height)
|
||||||
this.completePass(pass);
|
this.initEffectPass(pass)
|
||||||
},
|
},
|
||||||
__hmrId: 'SMAAPass',
|
__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