Skip to content

Camera Shake

<CameraShake /> 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 — and is based on the Drei CameraShake component.

Demo code
vue
<script setup lang="ts">
import { Backdrop, CameraShake, ContactShadows, Environment, OrbitControls, useGLTF } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { SRGBColorSpace } from 'three'
import { computed } from 'vue'

const gl = {
  clearColor: '#333',
  alpha: true,
  outputColorSpace: SRGBColorSpace,
}

const { state } = useGLTF('https://raw.githubusercontent.com/Tresjs/assets/main/models/gltf/ugly-naked-bunny/ugly-naked-bunny-animated.gltf', { draco: true })

const model = computed(() => state?.value?.scene)
</script>

<template>
  <div class="hud-overlay"></div>

  <TresCanvas
    v-bind="gl"
  >
    <TresPerspectiveCamera :position="[0, 1.25, 3]" />

    <TresGroup name="model" :position="[0, -0.5, 0]" :scale="[0.5, 0.5, 0.5]">
      <primitive v-if="model" :object="model" />
    </TresGroup>

    <Backdrop
      :floor="5"
      :segments="10"
      receive-shadow
      :scale="[20, 8.5, 1]"
      :position="[0, -0.5, -2]"
    >
      <TresMeshPhysicalMaterial color="orange" />
    </Backdrop>

    <ContactShadows
      :position="[0, -0.475, 0]"
      :scale="5"
      :blur="1"
      :opacity="0.5"
    />

    <TresAmbientLight :intensity="0.5" />

    <Suspense>
      <Environment preset="dawn" :environment-intensity="0.5" />
    </Suspense>

    <OrbitControls make-default :max-polar-angle="Math.PI / 2" />

    <CameraShake
      :intensity="1"
      :maxYaw="0.1"
      :maxPitch="0.05"
      :maxRoll="0.05"
      :yawFrequency="0.05"
      :pitchFrequency="0.2"
      :rollFrequency="0.2"
      :decayRate="0.65"
    />
  </TresCanvas>
</template>

<style scoped>
.hud-overlay {
  position: absolute;
  z-index: 2;
  width: 90%;
  height: 100%;
  background-image: url('/camera-shake/fake-hud.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  pointer-events: none;
  left: 50%;
  transform: translateX(-50%);
  aspect-ratio: 486 / 274;
}
</style>

Usage

You can use <CameraShake /> component without passing any props, but still if you want you can tweak the props to find the best setup for you

vue
<template>
  <TresCanvas>
    <TresPerspectiveCamera :position="[0, 2, 5]" />

    <!-- YOUR SCENE -->

    <OrbitControls make-default />
    <CameraShake :intensity="0.5" />
  </TresCanvas>
</template>

INFO

<CameraShake /> is fully compatible with <OrbitControls />. To ensure it works as expected, make sure to add the make-default prop:

vue
<OrbitControls make-default />

Props

PropDescriptionDefault
intensityControls the overall strength of the shake effect.1
decayEnables gradual reduction of shake intensity over time.false
decayRateSets the speed at which intensity decays per second when decay is enabled. Multiplied by delta each frame.0.65
maxYawMaximum amplitude for yaw (horizontal rotation) in radians.0.01
maxPitchMaximum amplitude for pitch (vertical rotation) in radians.0.01
maxRollMaximum amplitude for roll (tilt) in radians.0.01
yawFrequencyFrequency of yaw oscillation, used with elapsed time in Simplex noise calculations.0.1
pitchFrequencyFrequency of pitch oscillation.0.1
rollFrequencyFrequency of roll oscillation.0.1