home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: rec.games.programmer
- Path: sparky!uunet!uchinews!news
- From: greg@zaphod.uchicago.edu (Greg Kuperberg)
- Subject: Ghosts, multiple images, and flicker (and motion blur)
- Message-ID: <1992Dec23.191151.12044@midway.uchicago.edu>
- Sender: news@uchinews.uchicago.edu (News System)
- Organization: Dept. of Mathematics, U. of Chicago
- Date: Wed, 23 Dec 1992 19:11:51 GMT
- Lines: 131
-
- A response that I got for my postings about motion blur have prompted
- me to me make a big caveat about using motion blur:
-
- Motion blur is a fancy method in visual animation. Unless every other
- aspect of your animation timing is nearly perfect, motion blur is a
- lot of theoretical BS that you should ignore. The problem it solves is
- the strobe effect, which is similar to but not exactly the same as
- ghost images or double or triple images. If you are having one of
- these problems you should look very carefully to see which one, and
- unless it is the strobe effect motion blur might help some but might
- also be useless.
-
- In particular, you should first make sure that your animation is
- in synch with the vertical retrace on your monitor, which therefore
- means that you are using a form of clocked animation. Also,
- if your graphics could benefit greatly from some anti-aliasing, you
- might want to implement that before you try motion blur.
-
- Some more words about clocked animation. You should banish from
- your intuition the idea if your code is fast your animation will
- be fast and if your code is slow your animation will be slow.
- You should also qualify the notion that if part of your code takes
- a large portion of your CPU time then there is something wrong with
- that piece of code.
-
- When your code finishes computing and drawing the new frame, it
- will wait for the vertical retrace or clock tick because there is
- nothing else for it to do. A CPU cannot simply stop thinking without
- being turned off. If your code spends 90% of its time waiting for
- vertical retrace, your CPU budget is very healthy; you have loads
- of extra time. If your code spends 5% of its time waiting for the
- retrace, you can hardly afford any more animation than you already
- have.
-
- With clocked animation, if your code is fast your animation will be
- exactly the same as when your code is at a moderate speed. If your
- code is slow, it will miss clock ticks. Your animation will skip. It
- will stutter. It will not be just a little slower.
-
- When I explained how to set up clocked animation, I forgot about the
- case where you have no interrupts or counts available, you just have
- a flag that is YES during a vertical retrace and NO at other times.
- In this case your only choice for the animation loop is something
- of the form:
-
- for(;;)
- {
- ... /* Draw everything */
- while(!vertical_retrace_flag);
- }
-
- The problem is that if your code is slow, you will not be able to tell
- the difference between having extra time and missing the vertical
- retrace completely. You will not be able to borrow CPU time from the
- next frame. Instead your animation will with certainty skip a beat.
- That's the way the egg rolls and you have to make sure you live within
- your CPU budget to prevent it.
-
- Of all the advantages of clocked animation, I didn't mention that it
- helps you avoid double images and sprite flicker. You can't guarantee
- that unwanted pixels won't be sent to the phosphorus unless you are
- in synch with the vertical retrace. If you are, here are some tips
- on how to get the most out of it and maintain the visual integrity
- of your sprites:
-
- The cleanest way to avoid flicker and everything else is to use page
- flipping. There are two kinds: Hardware-driven and software-driven.
- With hardware-driven page flipping you tell your video chip to
- alternate between displaying two different stretches of RAM. You
- always draw on the one that isn't displayed. If you have hardware-driven
- page flipping, the vertical retrace is the ideal time to use it.
- That's exactly when the video chip isn't looking. Flipping pages when
- it is looking can mean ghosts and multiple images.
-
- You use software-driven page flipping when you can't or don't want to
- ask the video chip to move to a different part of your RAM. With
- software-driven page flipping you simply draw everything into an
- internal copy of the screen, then copy the whole shebang onto the
- real screen. It sounds redundant but it can be a good idea. But
- you might not be able to spare the CPU time. In that case you have
- no choice but to erase and draw your sprites or whatever directly on the
- video RAM.
-
- Whether you have software pages or you are drawing sprites directly,
- you are in a race with with CRT beam. It is important to stay
- ahead of the beam. That means you should draw all your sprites
- in order from top to bottom. It is also tempting to erase all
- your sprites and then redraw them all. But if you do that, you are
- running two laps while the beam is running one, and it is impossible
- to stay ahead the whole time. It will mean that some sprites will
- be caught when they are erased but not redrawn. In general you should
- try to minimize the amount of time between when a sprite are erased
- and when the same sprite is redrawn.
-
- If you have software page-flipping and you have only one retrace
- per animation frame, then presumably your screen copying routine is
- faster than the beam or else you wouldn't have any time left over.
- But you should still make sure that the bytes are copied in the same
- order as they are they will appear on the screen, and you should
- make sure to copy the screen immediately after the vertical retrace,
- not when you're finished with everything else in the frame.
- If you have, say, two retraces per frame then you are better off
- if the screen copy is twice as fast as the beam.
-
- If you have two or more retraces per frame and you can't flip pages, or
- if your animation is clocked to something other than the vertical
- retrace, then will you will simply have a lesser degree of perfection
- in your animation. It is still very important to minimize time
- between erase and draw for a given sprite, but even after you implement
- that you may still have problems with flicker, especially when sprites
- overlap. This was exactly my situation when I wrote J-Bird for the
- IBM-PC. My solution? Masked erasure. I already had to use a mask
- when drawing my sprites because I had a complicated background and the
- sprites could overlap. So I souped up the erase routine so that it
- would use the mask also. It wasn't perfect, because there was still
- some amount of "ghost erasure" when sprites overlapped, but it
- looked pretty good and even the ghost erasure looked kind-of neat.
-
- In fact, if I may toot my own horn, J-Bird went to the limit of the
- IBM-PC's CPU resources. I spent entire days trying to optimize my
- drawing routines, and the clock-tick pages of my 8088 manual got old
- and soiled as I tried to squeeze out every possible clock tick. Among
- other things, I didn't have the time to bit-shift the pixels in my
- sprites, so I had to have a copy of each sprite for every possible
- offset relative to the bytes of the video RAM. Not only the image, but
- the mask too, which was of course expanded to the same width as the
- image instead of just being a bit array. The result? More sprites
- doing more complicated things smoothly than any other game I saw on the
- market that would run on the original IBM. Bruce Artwick's Flight
- Simulator had much better graphics overall, but it didn't use
- sprites and it wasn't smooth.
-