From d7bb55d96ece6283a6d3e443e25e318e67189b51 Mon Sep 17 00:00:00 2001 From: Damien Montastier Date: Sat, 6 Sep 2025 10:59:28 +0200 Subject: [PATCH 1/6] feat: add CameraShake component --- docs/component-list/components.ts | 1 + .../vue/src/pages/staging/CameraShakeDemo.vue | 130 +++++++++++++++ playground/vue/src/router/routes/staging.ts | 5 + src/core/staging/CameraShake.vue | 152 ++++++++++++++++++ src/core/staging/index.ts | 2 + 5 files changed, 290 insertions(+) create mode 100644 playground/vue/src/pages/staging/CameraShakeDemo.vue create mode 100644 src/core/staging/CameraShake.vue diff --git a/docs/component-list/components.ts b/docs/component-list/components.ts index ce204469e..80c3d9583 100644 --- a/docs/component-list/components.ts +++ b/docs/component-list/components.ts @@ -124,6 +124,7 @@ export default [ { text: 'AccumulativeShadows', link: '/guide/staging/accumulative-shadows' }, { text: 'ContactShadows', link: '/guide/staging/contact-shadows' }, { text: 'Precipitation', link: '/guide/staging/precipitation' }, + { text: 'CameraShake', link: '/guide/staging/camera-shake' }, { text: 'Sparkles', link: '/guide/staging/sparkles' }, { text: 'Ocean', link: '/guide/staging/ocean' }, { text: 'Fit', link: '/guide/staging/fit' }, diff --git a/playground/vue/src/pages/staging/CameraShakeDemo.vue b/playground/vue/src/pages/staging/CameraShakeDemo.vue new file mode 100644 index 000000000..720b6b2ae --- /dev/null +++ b/playground/vue/src/pages/staging/CameraShakeDemo.vue @@ -0,0 +1,130 @@ + + + diff --git a/playground/vue/src/router/routes/staging.ts b/playground/vue/src/router/routes/staging.ts index a2e231d21..d23f857ac 100644 --- a/playground/vue/src/router/routes/staging.ts +++ b/playground/vue/src/router/routes/staging.ts @@ -4,6 +4,11 @@ export const stagingRoutes = [ name: 'Smoke', component: () => import('../../pages/staging/SmokeDemo.vue'), }, + { + path: '/staging/camera-shake', + name: 'CameraShake', + component: () => import('../../pages/staging/CameraShakeDemo.vue'), + }, { path: '/staging/precipitation', name: 'Precipitation', diff --git a/src/core/staging/CameraShake.vue b/src/core/staging/CameraShake.vue new file mode 100644 index 000000000..6ff7153ca --- /dev/null +++ b/src/core/staging/CameraShake.vue @@ -0,0 +1,152 @@ + + + diff --git a/src/core/staging/index.ts b/src/core/staging/index.ts index 02248a415..156809910 100644 --- a/src/core/staging/index.ts +++ b/src/core/staging/index.ts @@ -11,6 +11,7 @@ import CircleShadow from './CircleShadow.vue' import RandomizedLights from './RandomizedLights/component.vue' import Sky from './Sky.vue' import Smoke from './Smoke.vue' +import CameraShake from './CameraShake.vue' import SoftShadows from './SoftShadows.vue' import Sparkles from './Sparkles/component.vue' import Stage from './Stage.vue' @@ -23,6 +24,7 @@ export { Align, Backdrop, Bounds, + CameraShake, CircleShadow, ContactShadows, Environment, From ca63f468f0ae4ebfe12f9e2d309f0020e444971b Mon Sep 17 00:00:00 2001 From: Damien Montastier Date: Sat, 6 Sep 2025 11:02:15 +0200 Subject: [PATCH 2/6] fix: correct CameraShake behavior --- src/core/staging/CameraShake.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/staging/CameraShake.vue b/src/core/staging/CameraShake.vue index 6ff7153ca..375c2c321 100644 --- a/src/core/staging/CameraShake.vue +++ b/src/core/staging/CameraShake.vue @@ -99,8 +99,14 @@ const yawNoise = new SimplexNoise() const pitchNoise = new SimplexNoise() const rollNoise = new SimplexNoise() +function constrainIntensity() { + if (currentIntensity.value < 0) { currentIntensity.value = 0 } + if (currentIntensity.value > 1) { currentIntensity.value = 1 } +} + watch(intensity, (newVal) => { currentIntensity.value = newVal + constrainIntensity() }) function updateInitialRotation() { @@ -138,7 +144,7 @@ onBeforeRender(({ elapsed, delta }) => { if (decay.value && currentIntensity.value > 0) { currentIntensity.value -= decayRate.value * delta - if (currentIntensity.value < 0) { currentIntensity.value = 0 } + constrainIntensity() } }) From 6effe932b9246ed1d2021ee1f8e75034b288c20c Mon Sep 17 00:00:00 2001 From: Damien Montastier Date: Sat, 6 Sep 2025 14:50:41 +0200 Subject: [PATCH 3/6] docs: add CameraShake documentation and playground demo --- .../theme/components/CameraShakeDemo.vue | 84 +++++++++++++++++++ docs/guide/staging/camera-shake.md | 54 ++++++++++++ docs/public/camera-shake/fake-hud.svg | 1 + 3 files changed, 139 insertions(+) create mode 100644 docs/.vitepress/theme/components/CameraShakeDemo.vue create mode 100644 docs/guide/staging/camera-shake.md create mode 100644 docs/public/camera-shake/fake-hud.svg diff --git a/docs/.vitepress/theme/components/CameraShakeDemo.vue b/docs/.vitepress/theme/components/CameraShakeDemo.vue new file mode 100644 index 000000000..78f1ea0fd --- /dev/null +++ b/docs/.vitepress/theme/components/CameraShakeDemo.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/docs/guide/staging/camera-shake.md b/docs/guide/staging/camera-shake.md new file mode 100644 index 000000000..d72b4f898 --- /dev/null +++ b/docs/guide/staging/camera-shake.md @@ -0,0 +1,54 @@ +# Camera Shake + +`` is a component that adds **natural**, *noise-driven motion* to the **active camera**. +It offers **per-axis control**, **adjustable intensity**, and *optional decay* — perfect for *handheld feel*, *footsteps*, *impacts*, or *engine rumble*. + + + + + +
+ Demo code + + <<< @/.vitepress/theme/components/CameraShakeDemo.vue{0} +
+ +## Usage + +You can use `` component without passing any props, but still if you want you can tweak the props to find the best setup for you + +```vue{8} + +``` + +::: info +`` is fully compatible with **``**. +To ensure it works *as expected*, make sure to add the **`make-default`** prop: + +```vue + +``` +::: + +## Props + +| **Prop** | **Description** | **Default** | +|---------------------|-------------------------------------------------------------------------------------------------------------------|-------------| +| `intensity` | **Controls the overall strength** of the shake effect. | `1` | +| `decay` | **Enables gradual reduction** of shake intensity over time. | `false` | +| `decayRate` | **Sets the speed** at which intensity decays per second when `decay` is enabled. Multiplied by `delta` each frame.| `0.65` | +| `maxYaw` | **Maximum amplitude** for yaw (horizontal rotation) in radians. | `0.01` | +| `maxPitch` | **Maximum amplitude** for pitch (vertical rotation) in radians. | `0.01` | +| `maxRoll` | **Maximum amplitude** for roll (tilt) in radians. | `0.01` | +| `yawFrequency` | Frequency of **yaw oscillation**, used with elapsed time in Simplex noise calculations. | `0.1` | +| `pitchFrequency` | Frequency of **pitch oscillation**. | `0.1` | +| `rollFrequency` | Frequency of **roll oscillation**. | `0.1` | diff --git a/docs/public/camera-shake/fake-hud.svg b/docs/public/camera-shake/fake-hud.svg new file mode 100644 index 000000000..d894791ea --- /dev/null +++ b/docs/public/camera-shake/fake-hud.svg @@ -0,0 +1 @@ +REC00:00:00 \ No newline at end of file From ac1a4fba558ed77b3aa35a8ef20dfff32cf53ddb Mon Sep 17 00:00:00 2001 From: Damien Montastier Date: Sat, 6 Sep 2025 15:00:45 +0200 Subject: [PATCH 4/6] chore: apply global corrections to CameraShake source, docs and demo --- .../.vitepress/theme/components/CameraShakeDemo.vue | 13 ++++++------- src/core/staging/CameraShake.vue | 7 +++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/.vitepress/theme/components/CameraShakeDemo.vue b/docs/.vitepress/theme/components/CameraShakeDemo.vue index 78f1ea0fd..e7b583e67 100644 --- a/docs/.vitepress/theme/components/CameraShakeDemo.vue +++ b/docs/.vitepress/theme/components/CameraShakeDemo.vue @@ -1,15 +1,13 @@