Impulse

One-off camera shakes from events like explosions and hits.

Fire an impulse from anywhere in your game, and every camera listening to it reacts. Impulses live in an ImpulseField. The shared impulseField is enough unless you want separate event streams:

import { impulseField, ImpulseShapes } from '@pmndrs/klipp';

function onExplosion(position: [number, number, number]) {
  impulseField.generate({
    position,
    direction: [0, 0.5, 0],
    shape: ImpulseShapes.explosion,
    radius: 5,
    dissipationDistance: 15,
  });
}

A camera reacts once it has an ImpulseListener, a Noise.

Generating an impulse

OptionDescriptionDefault
positionWhere the impulse happens, in world space.
directionWhich way, and how far, the camera gets pushed at the peak. A bigger vector is a stronger kick.[0, 0, 0]
shapeHow the strength changes over time: ImpulseShapes.recoil, bump, explosion, rumble, or your own (t) => number.ImpulseShapes.bump
durationLength in seconds.0.4
radiusDistance from position where the impulse is felt at full strength.0
dissipationDistanceDistance beyond radius over which it fades out. 0 means it's felt everywhere.0
propagationSpeedHow fast it travels, in units per second, so faraway cameras feel it later.Infinity
channelBitmask to target specific listeners. See channelMask below.1

Listener settings

SettingDescriptionDefault
gainMultiplies the impulse strength. 0 mutes this listener.1
shakeAdds a rattle on top of the push. See below.
cameraSpaceTreat direction relative to the camera instead of the world. See below.false
channelMaskOnly react to impulses where channel & channelMask is not 0.1
fieldA separate ImpulseField to listen to instead of the shared impulseField.impulseField

Adding a rattle

An impulse on its own only pushes the camera. shake adds rotation and jitter that grows and fades with it. It's a BasicMultiChannelPerlin whose amplitudeGain follows the impulse strength.

Camera-relative impulses

By default direction is in world space, which suits explosions: the camera gets pushed away from where it happened. For recoil or a landing thump, use cameraSpace so the same direction always kicks the same way on screen.

Usage

import { ImpulseListenerNoise } from '@pmndrs/klipp';

camera.addNoise(new ImpulseListenerNoise());

Adding a rattle

import { BasicMultiChannelPerlinNoise } from '@pmndrs/klipp';

const shake = new BasicMultiChannelPerlinNoise({ positionAmplitude: [0.1, 0.1, 0.1], rotationAmplitude: [4, 4, 4] });
camera.addNoise(new ImpulseListenerNoise({ shake }));

Camera-relative

impulseField.generate({ position: [0, 0, 0], direction: [0, 0.3, 0.1], shape: ImpulseShapes.recoil });

camera.addNoise(new ImpulseListenerNoise({ cameraSpace: true }));