Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'd like to shake the camera around a bit during an explosion, and I've tried a few different functions for rocking it around, and nothing seems to really give that 'wow, what a bang!' type feeling that I'm looking for. I've tried some arbitrary relatively high frequency sine wave patterns with a bit of linear attenuation, as well as a square wave-type pattern. I've tried moving just one axis, two, and all three (although the dolly effect was barely noticeable in that case).

Does anyone know of a good camera shaking pattern?

share|improve this question
2  
Try to find some film footage of camera shakes after explosions and watch it in slow motion to see how the camera shakes and base your code on that. –  Skizz Jul 29 '10 at 10:19
    
I have the exact same problem - the wobble just looks too smooth –  Iain Jul 29 '10 at 16:53
    
The biggest problem I face when implementing a camera shake is that it seems the player character (which the camera focuses on) moves instead of the camera. The odd thing is that it is the camera that moves, if you look at the surroundings you notice, but since you're so focused on the player character your perception gets screwed. I am still trying to solve this - probably by changing the field of view when the camera moves away/towards the player. –  Kaj Aug 14 '10 at 6:50
add comment

5 Answers

up vote 32 down vote accepted

I've got decent camera shake by applying Perlin noise to the camera's orientation. It gives you a decent big jolt with higher frequency shaking built in, and can look really good.

http://mrl.nyu.edu/~perlin/doc/oscar.html has more details and sample code for generating noise.

share|improve this answer
3  
Oh, noise, why didn't I think of that... Afterall a bang i pretty much short burst of noise, isn't it... Excellent idea! –  falstro Jul 29 '10 at 13:45
    
good idea, is there anything you cant use perlin noise to solve? :P –  Cubed2D Jul 30 '10 at 8:21
1  
Noise is definitely the way to go, if you even picture the effect your after, its short changes of random motion in different directions. But it can't be a spasm, so you need brief sections of uniformity. Sounds like a perfect use for Perlin noise. –  Daniel Apr 22 '11 at 0:18
add comment

If you are referring to that juddering screen shake from an explosion, I have tried to implement this in my prototype game (it's 2d but should translate to 3d quite well, I expect). Take a look at the youtube video and see if that's what you're looking for - the screen shake kicks off about 1:35

Anyway, the way I achieved it was to create a viewport for the sceen and store the centre point (centre).

When an explosion kicks off, I create a random radius of ~30px. I then offset the viewport from centre by this many pixels in a random direction.

For each subsequent update (between draws to screen), I reduce radius by 10-20% and offset the viewport by this many pixels from centre again. However, instead of picking a random angle for this offset, I instead take the previous viewport angle from centre and added 180+/-60 degrees to it.

So basically, each update (or 10-20ms or so), I offset the viewport by a diminishing number of pixels from the centre of the screen.

Here's some pseudocode:

viewportCentre = (400,300) //Lets say screen size is 800 x 600
radius = 30.0
randomAngle = rand()%360
offset = ( sin(randomAngle) * radius , cos(randomAngle) * radius) //create offset 2d vector
viewport.setCentre(viewportCentre + offset) // set centre of viewport
draw()  

while(true)  //update about every 10-20ms
{ 
    radius *=0.9 //diminish radius each frame
    randomAngle +=(180 +\- rand()%60) //pick new angle 
    offset = (sin(randomAngle) * radius , cos(randomAngle) * radius) //create offset 2d vector
    viewport.setCentre(viewportCentre + offset) //set centre of viewport
    draw() //redraw
}

I usually stop the screen shake when radius gets lower than 2.0, at which point I reset the viewport back to centre.

share|improve this answer
1  
I like this implementation a lot, works perfectly for small 2D games. As a comment it is equivalent to do randomAngle += (150 + rand()%60) in order to get rid of any +/- problems. –  Krøllebølle Feb 4 '13 at 18:46
add comment

wkerslake is right, camera shakes appear to be more complex than you might think.

When emulating a shaking camera you'd have to think about what type of camera (operator) you want to mimic. The weight of the camera affects inertia, eg. heavier cameras smooth out small 'random' movements. A camera operator on a rail or in a car adds additional noise.

Using Perlin or Simplex noise is definitely an option, then it's all about finding the right balance between different noise ratios. But I found using interpolation between values is less computationally intensive and can be just as effective.

A while ago, I've found a Maya script that seems to get a lot of things right. You could take a look at that.

Also, you might want to take a look at Gran Turismo (5), their team did an impressive job at doing various types of realtime camera shaking when you watch a replay in the game.

share|improve this answer
add comment

To make a camera shake "feel" correct is less about the direction of motion and more about acceleration curves.

Camera shakes are diving into the realm of animation and so all the rules of action/reaction apply. If you are moving in a linear fashion from point to point it will feel smooth and uniform and not like an impact.

If you shake your head back and forth you'll notice that it moves fastest at the midpoint between changing direction and slows down on each side as you first have to decelerate and then start up in the new direction.

Here is a listing of various easing functions to apply to your motion. You might want to only EaseOut the first motion to make it feel a little more abrupt, and then EaseInOut the rest to simulate the head/camera movement.

share|improve this answer
    
I think easing would still make it too smooth. The perlin noise seem like a good idea, or otherwise a plain random with the random range diminishing to zero over time to make it fade out (I would rather experiment with different ease functions on the diminishing radius than on the actual movement, easing the movement itself will make the camera feel like it's on a spring, doesn't feel right with camera shake in my experience). –  Kaj Aug 14 '10 at 6:48
add comment

If you've got dynamic object physics [probably not the right word, but sort of what I mean], where any objects not fixed would be 'blown away' by the explosion, you could have the camera affected as an object like that.
Only difference would be just change the rotation/pitch/yaw/roll of the camera, and not the position.
Other than that, maybe generate a random number sequence and convert those to rotation somehow? Think that heightmap, grayscale stuff may be an example; they're not totally different, but are random.

share|improve this answer
    
+1 interesting idea, I think I'll try the noise movement, and when I've got that running, I'll try to add a more smoth dolly effect, sort of as if the camera was attached to a spring and pressed backwards by the shock. –  falstro Jul 30 '10 at 7:55
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.