From 786555ea5cdff0a39e1499370e962890ea7629a9 Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Sun, 2 May 2021 01:07:31 +0200 Subject: [PATCH 1/9] vanruesc/postprocessing wip --- .../postprocessing/vanruesc/Effect.ts | 80 +++++++++++++++++++ .../postprocessing/vanruesc/EffectComposer.ts | 49 ++++++++++++ .../postprocessing/vanruesc/EffectPass.ts | 75 +++++++++++++++++ .../postprocessing/vanruesc/Pass.ts | 61 ++++++++++++++ .../postprocessing/vanruesc/index.ts | 4 + 5 files changed, 269 insertions(+) create mode 100644 src/components/postprocessing/vanruesc/Effect.ts create mode 100644 src/components/postprocessing/vanruesc/EffectComposer.ts create mode 100644 src/components/postprocessing/vanruesc/EffectPass.ts create mode 100644 src/components/postprocessing/vanruesc/Pass.ts create mode 100644 src/components/postprocessing/vanruesc/index.ts diff --git a/src/components/postprocessing/vanruesc/Effect.ts b/src/components/postprocessing/vanruesc/Effect.ts new file mode 100644 index 0000000..0613ce8 --- /dev/null +++ b/src/components/postprocessing/vanruesc/Effect.ts @@ -0,0 +1,80 @@ +import { defineComponent, inject, onUnmounted, PropType } from 'vue' +import { LoadingManager } from 'three' +// @ts-ignore +import * as PP from 'postprocessing' +// import { RendererInterface } from '../../../build/trois' +import { RendererInterface } from '../../../export' +import { EffectPassInjectionKey } from './EffectPass' + +type EffectTypes = 'bloom' | 'dof' | 'smaa' + +export default defineComponent({ + props: { + type: { type: String as PropType, required: true }, + options: { type: Object, default: () => ({}) }, + }, + setup(props) { + const effectPass = inject(EffectPassInjectionKey) + if (!effectPass) { + console.error('EffectPass not found') + return + } + + let effect: undefined | PP.Effect // not useful + const effectIndex = effectPass.getEffectIndex() + // console.log(effectIndex) + + const initEffect = (params: any = undefined) => { + effect = createEffect(effectPass.composer.renderer, props.type, props.options, params) + if (!effect) { + console.error('Invalid effect type') + return + } + effectPass.addEffect(effect, effectIndex) + } + + onUnmounted(() => { + if (effect) { + effectPass.removeEffect(effect) + effect.dispose() + } + }) + + if (props.type === 'smaa') { + const smaaImageLoader = new PP.SMAAImageLoader(new LoadingManager()) + smaaImageLoader.load(([search, area]: [HTMLImageElement, HTMLImageElement]) => { + initEffect({ smaaSearch: search, smaaArea: area }) + }) + } else { + initEffect() + } + }, + render() { return [] }, +}) + +function createEffect( + renderer: RendererInterface, + type: string, + options: Record, + assets: any = undefined +): PP.Effect { + let effect + switch (type) { + case 'bloom' : + effect = new PP.BloomEffect(options) + break + case 'dof' : + effect = new PP.DepthEffect(renderer, options) + break + case 'smaa' : + effect = createSmaaEffect(options, assets) + break + } + return effect +} + +function createSmaaEffect(options: Record, assets: any): PP.Pass { + const { smaaSearch, smaaArea } = assets + // TODO : options + return new PP.SMAAEffect(smaaSearch, smaaArea) +} diff --git a/src/components/postprocessing/vanruesc/EffectComposer.ts b/src/components/postprocessing/vanruesc/EffectComposer.ts new file mode 100644 index 0000000..7b0f74d --- /dev/null +++ b/src/components/postprocessing/vanruesc/EffectComposer.ts @@ -0,0 +1,49 @@ +import { defineComponent, inject, InjectionKey, onUnmounted, provide } from 'vue' +import { Clock } from 'three' +// @ts-ignore +import * as PP from 'postprocessing' +// import { RendererInjectionKey, RendererInterface } from '../../../build/trois' +import { RendererInjectionKey, RendererInterface } from '../../../export' + +export interface EffectComposerInterface { + renderer: RendererInterface + composer: PP.EffectComposer + getPassIndex: {(): number} +} + +export const ComposerInjectionKey: InjectionKey = Symbol('Composer') + +export default defineComponent({ + setup() { + const renderer = inject(RendererInjectionKey) + if (!renderer) { + console.error('Renderer not found') + return + } + + const composer = new PP.EffectComposer(renderer.renderer) + const clock = new Clock() + const render = () => { composer.render(clock.getDelta()) } + const setSize = () => { composer.setSize(renderer.size.width, renderer.size.height) } + + let passIndex = 0 + const getPassIndex = () => { return passIndex++ } + + renderer.onInit(() => { + renderer.renderer.autoClear = false + renderer.renderFn = render + setSize() + renderer.onResize(setSize) + }) + + onUnmounted(() => { + renderer.offResize(setSize) + composer.dispose() + }) + + provide(ComposerInjectionKey, { renderer, composer, getPassIndex }) + }, + render() { + return this.$slots.default ? this.$slots.default() : [] + }, +}) diff --git a/src/components/postprocessing/vanruesc/EffectPass.ts b/src/components/postprocessing/vanruesc/EffectPass.ts new file mode 100644 index 0000000..6b4bc67 --- /dev/null +++ b/src/components/postprocessing/vanruesc/EffectPass.ts @@ -0,0 +1,75 @@ +import { defineComponent, inject, InjectionKey, onUnmounted, provide } from 'vue' +// @ts-ignore +import * as PP from 'postprocessing' +import { ComposerInjectionKey, EffectComposerInterface } from './EffectComposer' + +export interface EffectPassInterface { + composer: EffectComposerInterface + effectPass: PP.EffectPass + effects: Array + getEffectIndex: {(): number} + addEffect: {(effect: PP.Effect, index: number): number} + removeEffect: {(effect: PP.Effect): number} +} + +export const EffectPassInjectionKey: InjectionKey = Symbol('Composer') + +export default defineComponent({ + props: { + // needsSwap: { type: Boolean, default: false }, + renderToScreen: { type: Boolean, default: false }, + }, + setup() { + const composer = inject(ComposerInjectionKey) + if (!composer) { + console.error('Composer not found') + return {} + } + + const passIndex = composer.getPassIndex() + let effectPass: PP.EffectPass + + const effects: Array = [] + let effectIndex = 0 + const getEffectIndex = () => { return effectIndex++ } + + const refreshEffectPass = () => { + // we have to recreate EffectPass (modifying effectPass.effects don't work) + if (effectPass) { + composer.composer.removePass(effectPass) + effectPass.dispose() + } + effectPass = new PP.EffectPass(composer.renderer.camera, ...effects) + composer.composer.addPass(effectPass, passIndex) + } + + const addEffect = (effect: PP.Effect, index: number) => { + effects.splice(index, 1, effect) + refreshEffectPass() + } + + const removeEffect = (effect: PP.Effect) => { + const index = effects.indexOf(effect) + if (index >= 0) { + effects.splice(index, 1) + refreshEffectPass() + } + } + + onUnmounted(() => { + if (effectPass) { + composer.composer.removePass(effectPass) + effectPass.dispose() + } + }) + + provide(EffectPassInjectionKey, { + composer, + effectPass, + effects, + getEffectIndex, + addEffect, removeEffect, + }) + }, + render() { return this.$slots.default ? this.$slots.default() : [] }, +}) diff --git a/src/components/postprocessing/vanruesc/Pass.ts b/src/components/postprocessing/vanruesc/Pass.ts new file mode 100644 index 0000000..61b3d21 --- /dev/null +++ b/src/components/postprocessing/vanruesc/Pass.ts @@ -0,0 +1,61 @@ +import { defineComponent, inject, onUnmounted, PropType } from 'vue' +// @ts-ignore +import * as PP from 'postprocessing' +import { ComposerInjectionKey } from './EffectComposer' +// import { RendererInterface } from '../../../build/trois' +import { RendererInterface } from '../../../export' + +type PassTypes = 'render' + +export default defineComponent({ + props: { + type: { type: String as PropType, required: true }, + options: { type: Object, default: () => ({}) }, + // needsSwap: { type: Boolean, default: false }, + renderToScreen: { type: Boolean, default: false }, + }, + setup(props) { + const composer = inject(ComposerInjectionKey) + if (!composer || !composer.renderer) { + console.error('Composer/Renderer not found') + return {} + } + + let pass: undefined | PP.Pass + const passIndex = composer.getPassIndex() + + const initPass = (params: any = undefined) => { + pass = createPass(composer.renderer, props.type, props.options) + if (!pass) { + console.error('Invalid pass type') + return + } + pass.renderToScreen = props.renderToScreen + composer.composer.addPass(pass, passIndex) + } + + onUnmounted(() => { + if (pass) { + composer.composer.removePass(pass) + pass.dispose() + } + }) + + initPass() + }, + render() { return [] }, +}) + +function createPass( + renderer: RendererInterface, + type: string, + options: Record +): PP.Pass { + let pass + switch (type) { + case 'render' : + pass = new PP.RenderPass(renderer.scene, renderer.camera) + break + } + return pass +} diff --git a/src/components/postprocessing/vanruesc/index.ts b/src/components/postprocessing/vanruesc/index.ts new file mode 100644 index 0000000..98b1c8e --- /dev/null +++ b/src/components/postprocessing/vanruesc/index.ts @@ -0,0 +1,4 @@ +export { default as EffectComposer } from './EffectComposer' +export { default as Pass } from './Pass' +export { default as EffectPass } from './EffectPass' +export { default as Effect } from './Effect' From 561ae0938dbcbb43d5e90306ecd58a04f5188caa Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Sun, 2 May 2021 01:32:50 +0200 Subject: [PATCH 2/9] fix dof --- src/components/postprocessing/vanruesc/Effect.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/postprocessing/vanruesc/Effect.ts b/src/components/postprocessing/vanruesc/Effect.ts index 0613ce8..0555d69 100644 --- a/src/components/postprocessing/vanruesc/Effect.ts +++ b/src/components/postprocessing/vanruesc/Effect.ts @@ -64,7 +64,7 @@ function createEffect( effect = new PP.BloomEffect(options) break case 'dof' : - effect = new PP.DepthEffect(renderer, options) + effect = new PP.DepthOfFieldEffect(renderer, options) break case 'smaa' : effect = createSmaaEffect(options, assets) From 1fe694743c4b9c3183f105a77408cd6a745f9cb0 Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Sun, 2 May 2021 20:16:23 +0200 Subject: [PATCH 3/9] wip : godrays --- .../postprocessing/vanruesc/Effect.ts | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/components/postprocessing/vanruesc/Effect.ts b/src/components/postprocessing/vanruesc/Effect.ts index 0555d69..5757b4e 100644 --- a/src/components/postprocessing/vanruesc/Effect.ts +++ b/src/components/postprocessing/vanruesc/Effect.ts @@ -1,12 +1,10 @@ -import { defineComponent, inject, onUnmounted, PropType } from 'vue' +import { defineComponent, inject, onMounted, onUnmounted, PropType } from 'vue' import { LoadingManager } from 'three' // @ts-ignore import * as PP from 'postprocessing' -// import { RendererInterface } from '../../../build/trois' -import { RendererInterface } from '../../../export' -import { EffectPassInjectionKey } from './EffectPass' +import { EffectPassInjectionKey, EffectPassInterface } from './EffectPass' -type EffectTypes = 'bloom' | 'dof' | 'smaa' +type EffectTypes = 'bloom' | 'dof' | 'godrays' | 'smaa' export default defineComponent({ props: { @@ -22,10 +20,9 @@ export default defineComponent({ let effect: undefined | PP.Effect // not useful const effectIndex = effectPass.getEffectIndex() - // console.log(effectIndex) const initEffect = (params: any = undefined) => { - effect = createEffect(effectPass.composer.renderer, props.type, props.options, params) + effect = createEffect(effectPass, props.type, props.options, params) if (!effect) { console.error('Invalid effect type') return @@ -33,27 +30,29 @@ export default defineComponent({ effectPass.addEffect(effect, effectIndex) } + onMounted(() => { + if (props.type === 'smaa') { + const smaaImageLoader = new PP.SMAAImageLoader(new LoadingManager()) + smaaImageLoader.load(([search, area]: [HTMLImageElement, HTMLImageElement]) => { + initEffect({ smaaSearch: search, smaaArea: area }) + }) + } else { + initEffect() + } + }) + onUnmounted(() => { if (effect) { effectPass.removeEffect(effect) effect.dispose() } }) - - if (props.type === 'smaa') { - const smaaImageLoader = new PP.SMAAImageLoader(new LoadingManager()) - smaaImageLoader.load(([search, area]: [HTMLImageElement, HTMLImageElement]) => { - initEffect({ smaaSearch: search, smaaArea: area }) - }) - } else { - initEffect() - } }, render() { return [] }, }) function createEffect( - renderer: RendererInterface, + effectPass: EffectPassInterface, type: string, options: Record, assets: any = undefined @@ -64,7 +63,10 @@ function createEffect( effect = new PP.BloomEffect(options) break case 'dof' : - effect = new PP.DepthOfFieldEffect(renderer, options) + effect = new PP.DepthOfFieldEffect(effectPass.composer.renderer, options) + break + case 'godrays' : + effect = createGodraysEffect(effectPass, options) break case 'smaa' : effect = createSmaaEffect(options, assets) @@ -78,3 +80,22 @@ function createSmaaEffect(options: Record, assets: any): PP.Pass { // TODO : options return new PP.SMAAEffect(smaaSearch, smaaArea) } + +function createGodraysEffect(effectPass: EffectPassInterface, options: Record): PP.Pass { + const opts = { ...options } + const { lightSource } = options + if (!lightSource) { + console.error('Invalid lightSource') + return + } + delete opts.lightSource + + // @ts-ignore + const lightSourceMesh = effectPass.composer.renderer.$root.$refs[lightSource]?.mesh + if (!lightSourceMesh) { + console.error('Invalid lightSource ref') + return + } + + return new PP.GodRaysEffect(effectPass.composer.renderer.camera, lightSourceMesh, opts) +} From 80bcc98b1554370d6dca81827932eda20c46a0f7 Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Sun, 2 May 2021 21:10:48 +0200 Subject: [PATCH 4/9] wip --- src/components/postprocessing/vanruesc/Effect.ts | 9 ++++----- src/components/postprocessing/vanruesc/EffectComposer.ts | 6 +++--- src/components/postprocessing/vanruesc/EffectPass.ts | 3 +++ src/components/postprocessing/vanruesc/Pass.ts | 6 +++--- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/components/postprocessing/vanruesc/Effect.ts b/src/components/postprocessing/vanruesc/Effect.ts index 5757b4e..d3f1df7 100644 --- a/src/components/postprocessing/vanruesc/Effect.ts +++ b/src/components/postprocessing/vanruesc/Effect.ts @@ -84,18 +84,17 @@ function createSmaaEffect(options: Record, assets: any): PP.Pass { function createGodraysEffect(effectPass: EffectPassInterface, options: Record): PP.Pass { const opts = { ...options } const { lightSource } = options - if (!lightSource) { + if (typeof lightSource !== 'string') { console.error('Invalid lightSource') return } delete opts.lightSource - // @ts-ignore - const lightSourceMesh = effectPass.composer.renderer.$root.$refs[lightSource]?.mesh - if (!lightSourceMesh) { + const lightSourceComp = effectPass.renderer.$root?.$refs[lightSource] as any + if (!lightSourceComp) { console.error('Invalid lightSource ref') return } - return new PP.GodRaysEffect(effectPass.composer.renderer.camera, lightSourceMesh, opts) + return new PP.GodRaysEffect(effectPass.composer.renderer.camera, lightSourceComp.mesh, opts) } diff --git a/src/components/postprocessing/vanruesc/EffectComposer.ts b/src/components/postprocessing/vanruesc/EffectComposer.ts index 7b0f74d..e6ee76e 100644 --- a/src/components/postprocessing/vanruesc/EffectComposer.ts +++ b/src/components/postprocessing/vanruesc/EffectComposer.ts @@ -2,11 +2,11 @@ import { defineComponent, inject, InjectionKey, onUnmounted, provide } from 'vue import { Clock } from 'three' // @ts-ignore import * as PP from 'postprocessing' -// import { RendererInjectionKey, RendererInterface } from '../../../build/trois' -import { RendererInjectionKey, RendererInterface } from '../../../export' +// import { RendererInjectionKey, RendererPublicInterface } from '../../../build/trois' +import { RendererInjectionKey, RendererPublicInterface } from '../../../export' export interface EffectComposerInterface { - renderer: RendererInterface + renderer: RendererPublicInterface composer: PP.EffectComposer getPassIndex: {(): number} } diff --git a/src/components/postprocessing/vanruesc/EffectPass.ts b/src/components/postprocessing/vanruesc/EffectPass.ts index 6b4bc67..68bb56a 100644 --- a/src/components/postprocessing/vanruesc/EffectPass.ts +++ b/src/components/postprocessing/vanruesc/EffectPass.ts @@ -2,9 +2,11 @@ import { defineComponent, inject, InjectionKey, onUnmounted, provide } from 'vue // @ts-ignore import * as PP from 'postprocessing' import { ComposerInjectionKey, EffectComposerInterface } from './EffectComposer' +import { RendererPublicInterface } from '../../../export' export interface EffectPassInterface { composer: EffectComposerInterface + renderer: RendererPublicInterface effectPass: PP.EffectPass effects: Array getEffectIndex: {(): number} @@ -65,6 +67,7 @@ export default defineComponent({ provide(EffectPassInjectionKey, { composer, + renderer: composer.renderer, effectPass, effects, getEffectIndex, diff --git a/src/components/postprocessing/vanruesc/Pass.ts b/src/components/postprocessing/vanruesc/Pass.ts index 61b3d21..6f585e6 100644 --- a/src/components/postprocessing/vanruesc/Pass.ts +++ b/src/components/postprocessing/vanruesc/Pass.ts @@ -2,8 +2,8 @@ import { defineComponent, inject, onUnmounted, PropType } from 'vue' // @ts-ignore import * as PP from 'postprocessing' import { ComposerInjectionKey } from './EffectComposer' -// import { RendererInterface } from '../../../build/trois' -import { RendererInterface } from '../../../export' +// import { RendererPublicInterface } from '../../../build/trois' +import { RendererPublicInterface } from '../../../export' type PassTypes = 'render' @@ -47,7 +47,7 @@ export default defineComponent({ }) function createPass( - renderer: RendererInterface, + renderer: RendererPublicInterface, type: string, options: Record ): PP.Pass { From fb0a98cba44b47b708454940786ea2af153929c5 Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Sun, 2 May 2021 21:25:59 +0200 Subject: [PATCH 5/9] blur pass --- src/components/postprocessing/vanruesc/Pass.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/postprocessing/vanruesc/Pass.ts b/src/components/postprocessing/vanruesc/Pass.ts index 6f585e6..bf2a832 100644 --- a/src/components/postprocessing/vanruesc/Pass.ts +++ b/src/components/postprocessing/vanruesc/Pass.ts @@ -5,7 +5,7 @@ import { ComposerInjectionKey } from './EffectComposer' // import { RendererPublicInterface } from '../../../build/trois' import { RendererPublicInterface } from '../../../export' -type PassTypes = 'render' +type PassTypes = 'render' | 'blur' export default defineComponent({ props: { @@ -56,6 +56,9 @@ function createPass( case 'render' : pass = new PP.RenderPass(renderer.scene, renderer.camera) break + case 'blur' : + pass = new PP.BlurPass(options) + break } return pass } From 2070f20a6b377901522a393a02bf8f056635c1fc Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Sun, 2 May 2021 22:05:24 +0200 Subject: [PATCH 6/9] add ready event on effect and pass --- src/components/postprocessing/vanruesc/Effect.ts | 6 +++++- src/components/postprocessing/vanruesc/Pass.ts | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/postprocessing/vanruesc/Effect.ts b/src/components/postprocessing/vanruesc/Effect.ts index d3f1df7..a10048e 100644 --- a/src/components/postprocessing/vanruesc/Effect.ts +++ b/src/components/postprocessing/vanruesc/Effect.ts @@ -10,6 +10,7 @@ export default defineComponent({ props: { type: { type: String as PropType, required: true }, options: { type: Object, default: () => ({}) }, + onReady: Function, }, setup(props) { const effectPass = inject(EffectPassInjectionKey) @@ -27,6 +28,7 @@ export default defineComponent({ console.error('Invalid effect type') return } + props.onReady?.(effect) effectPass.addEffect(effect, effectIndex) } @@ -78,7 +80,9 @@ function createEffect( function createSmaaEffect(options: Record, assets: any): PP.Pass { const { smaaSearch, smaaArea } = assets // TODO : options - return new PP.SMAAEffect(smaaSearch, smaaArea) + const params = [options.preset ?? PP.SMAAPreset.HIGH, options.edgeDetectionMode ?? PP.EdgeDetectionMode.COLOR] + console.log(params) + return new PP.SMAAEffect(smaaSearch, smaaArea, ...params) } function createGodraysEffect(effectPass: EffectPassInterface, options: Record): PP.Pass { diff --git a/src/components/postprocessing/vanruesc/Pass.ts b/src/components/postprocessing/vanruesc/Pass.ts index bf2a832..5b8895f 100644 --- a/src/components/postprocessing/vanruesc/Pass.ts +++ b/src/components/postprocessing/vanruesc/Pass.ts @@ -13,6 +13,7 @@ export default defineComponent({ options: { type: Object, default: () => ({}) }, // needsSwap: { type: Boolean, default: false }, renderToScreen: { type: Boolean, default: false }, + onReady: Function, }, setup(props) { const composer = inject(ComposerInjectionKey) @@ -31,6 +32,7 @@ export default defineComponent({ return } pass.renderToScreen = props.renderToScreen + props.onReady?.(pass) composer.composer.addPass(pass, passIndex) } From 2ce7fe87996494454fe33e303fee7cfc231564d9 Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Mon, 3 May 2021 23:31:17 +0200 Subject: [PATCH 7/9] remove console.log --- src/components/postprocessing/vanruesc/Effect.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/postprocessing/vanruesc/Effect.ts b/src/components/postprocessing/vanruesc/Effect.ts index a10048e..5568446 100644 --- a/src/components/postprocessing/vanruesc/Effect.ts +++ b/src/components/postprocessing/vanruesc/Effect.ts @@ -81,7 +81,6 @@ function createSmaaEffect(options: Record, assets: any): PP.Pass { const { smaaSearch, smaaArea } = assets // TODO : options const params = [options.preset ?? PP.SMAAPreset.HIGH, options.edgeDetectionMode ?? PP.EdgeDetectionMode.COLOR] - console.log(params) return new PP.SMAAEffect(smaaSearch, smaaArea, ...params) } From 2029497e112778d19ec8f79a65ee82d4ea29f8d2 Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Wed, 5 May 2021 09:47:54 +0200 Subject: [PATCH 8/9] fix setTexture --- src/materials/Material.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/materials/Material.ts b/src/materials/Material.ts index f2270f3..5e15b2b 100644 --- a/src/materials/Material.ts +++ b/src/materials/Material.ts @@ -61,7 +61,7 @@ const BaseMaterial = defineComponent({ material.needsUpdate = needsUpdate }, setTexture(texture: Texture | null, key = 'map') { - this.setProp(this, key, texture, true) + this.setProp(this.material, key, texture, true) }, }, render() { From 802b299e77d9fafdf639a2e41d7bed562e39f4cf Mon Sep 17 00:00:00 2001 From: Kevin Levron Date: Wed, 5 May 2021 21:35:11 +0200 Subject: [PATCH 9/9] add camera props --- src/core/Camera.ts | 9 +++++++++ src/core/OrthographicCamera.ts | 12 +++++------- src/core/PerspectiveCamera.ts | 13 ++++++------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/core/Camera.ts b/src/core/Camera.ts index e6df469..129956e 100644 --- a/src/core/Camera.ts +++ b/src/core/Camera.ts @@ -12,6 +12,10 @@ export default defineComponent({ // TODO: eventually extend Object3D // extends: Object3D, + props: { + props: { type: Object, default: () => ({}) }, + }, + // inject: { renderer: RendererInjectionKey as symbol }, // setup(): CameraSetupInterface { @@ -22,3 +26,8 @@ export default defineComponent({ return this.$slots.default ? this.$slots.default() : [] }, }) + +export function cameraSetProp(camera: any, key: string, value: any, updateProjectionMatrix = true) { + camera[key] = value + if (updateProjectionMatrix) camera.updateProjectionMatrix() +} diff --git a/src/core/OrthographicCamera.ts b/src/core/OrthographicCamera.ts index 783eaa8..6034162 100644 --- a/src/core/OrthographicCamera.ts +++ b/src/core/OrthographicCamera.ts @@ -1,7 +1,7 @@ import { defineComponent, inject, PropType, watch } from 'vue' import { OrthographicCamera } from 'three' -import { bindProp } from '../tools' -import Camera from './Camera' +import { bindObjectProp, bindProp } from '../tools' +import Camera, { cameraSetProp } from './Camera' import { Vector3PropInterface } from './Object3D' import { RendererInjectionKey } from './Renderer' @@ -29,14 +29,12 @@ export default defineComponent({ renderer.camera = camera bindProp(props, 'position', camera) + bindObjectProp(props, 'props', camera, true, cameraSetProp); - const watchProps = ['left', 'right', 'top', 'bottom', 'near', 'far', 'zoom'] - watchProps.forEach(p => { + ['left', 'right', 'top', 'bottom', 'near', 'far', 'zoom'].forEach(p => { // @ts-ignore watch(() => props[p], (value) => { - // @ts-ignore - camera[p] = value - camera.updateProjectionMatrix() + cameraSetProp(camera, p, value) }) }) diff --git a/src/core/PerspectiveCamera.ts b/src/core/PerspectiveCamera.ts index 5147a3f..ac9001b 100644 --- a/src/core/PerspectiveCamera.ts +++ b/src/core/PerspectiveCamera.ts @@ -1,7 +1,7 @@ import { defineComponent, inject, PropType, watch } from 'vue' import { PerspectiveCamera } from 'three' -import { bindProp } from '../tools' -import Camera from './Camera' +import { bindObjectProp, bindProp } from '../tools' +import Camera, { cameraSetProp } from './Camera' import { Vector3PropInterface } from './Object3D' import { RendererInjectionKey } from './Renderer' @@ -31,13 +31,12 @@ export default defineComponent({ if (props.lookAt) camera.lookAt(props.lookAt.x ?? 0, props.lookAt.y, props.lookAt.z) watch(() => props.lookAt, (v) => { camera.lookAt(v.x ?? 0, v.y, v.z) }, { deep: true }) - const watchProps = ['aspect', 'far', 'fov', 'near'] - watchProps.forEach(p => { + bindObjectProp(props, 'props', camera, true, cameraSetProp); + + ['aspect', 'far', 'fov', 'near'].forEach(p => { // @ts-ignore watch(() => props[p], (value) => { - // @ts-ignore - camera[p] = value - camera.updateProjectionMatrix() + cameraSetProp(camera, p, value) }) })