6
\$\begingroup\$

Some of you may know fraxy...

Basically, I was watching this video: http://www.youtube.com/watch?v=uL7zWdDCtOE And there are some times where some sprites spin really fast (4:00 mark for example), and I cannot figure how the motion blur effect was done.

I looked in the game folder, and found the sprite, it certainly does not has the blur added to it (in fact, it is even a .bmp! Not a PNG or anything that supporta alpha natively), and the engine IF using OpenGL, may not be clear (the resolution is fairly low too), also nothing else is getting blurred (so the effect is localized to some sprites... if you pay attention there are other moving objects that get blurry too).

So, how they do this glowing blur?

EDIT: On the video I am talking about the two things "spinning" in the left and right edge of the screen, they are shooting, and the sprite of their bullets are the same as their own sprite, but if you pay attention as they spin their sprites leave a trail, actually if you put the video some seconds before, you will see with the screen more empty, and the effect can be seen clearly.

EDIT2: I don't think Fraxy use shaders, and I am sure it does not use OpenGL either (since it run on computers that don't run OpenGL games). I know it is easy to do with shaders, with per-pixel calculations, I am asking how to do WITHOUT them.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Downvoted: Question makes lots of references to a video that has since been deleted \$\endgroup\$ Aug 8, 2016 at 11:36

4 Answers 4

11
\$\begingroup\$

Difficult to tell from the video exactly what you mean, but the simplest method of doing a sprite-based motion blur would just be to render the sprite several times, with some form of translucency.

You could buffer the previous positions for use as the trail, or you could use a small time-step in the animation to render sub-frames.

From the video in question I'd suggest a basic additive blend would work, which means you don't need alpha either in the texture or even in the vertex - just darken the sprite for the "trail".

Over-writing the same pixels makes them brighter, for the glow. If you have even a very dark glow around the object in the original image, you'll get a glowing halo if you additively blend a bunch together.

Alternatively you could use a basic HDR-like hack as a post-process. Take the image without any glow, threshold it so you only have very bright pixels, blur it a lot, and add it back in to the original. TBH I don't think that's necessary here.

\$\endgroup\$
1
  • \$\begingroup\$ Awesome, I didn't know motion blur was that straight-forward. \$\endgroup\$
    – ashes999
    Oct 20, 2011 at 1:08
1
\$\begingroup\$

I couldn´t see what you meant in the video, but for doing some motion blur I would store the sprites motion vectors and use then to do the blur. Rendering the sprite multiple times don´t look that good in my opnion.

If the sprite is spinning you would need the motion vectors for each pixel and this can be costly.

\$\endgroup\$
2
  • \$\begingroup\$ If you want to do a motion-blur like that, you could blur in the pixel-shader for the sprite, rather than as a post-process. Sprites, being 2D, are an easier case than 3D geometry. \$\endgroup\$
    – JasonD
    Aug 28, 2010 at 16:08
  • \$\begingroup\$ Yes, I should´ve been more specif, I was thinking of doing this at draw time. \$\endgroup\$
    – vshade
    Aug 28, 2010 at 21:02
0
\$\begingroup\$

Doing this with out a shader is going to be costly anyway. The only non costly way of doing this is without shaders is using multiple sprites as explained by Jason D. If you place the sprites progressively over the image you will still get the effect you are looking for with spinning sprites.

\$\endgroup\$
0
\$\begingroup\$

JasonD's answer was also acceptable for me.

Here is the code block I wrote. I create 2 extra sprites and put delay of 1-3 frames and see the effect I want:

public class BlurFollower : MonoBehaviour {


  //Generally values between 2-4 are well for me.
  public int DelayInFrames;
  //The sprite that we will follow
  public SpriteRenderer TargetSpriteRenderer;
  //The transparent sprite that will follow target
  public SpriteRenderer GhostSpriteRenderer;

  Vector3[] _positions;
  int[] _sortOrders;

  void Awake () {
    //At the begining there are no sprites
    GhostSpriteRenderer.enabled = false;
    _positions = new Vector3[DelayInFrames];
    _sortOrders = new int[DelayInFrames];
  }

  //when wait time (enough frames passed) this will be set true.
  bool delayCompleted = false;
  //frame counter
  int  count;


  void Update () {

    //Record targets position and sorting order.
    //You may also record sprite if you need it.
    _positions[count] = TargetSpriteRenderer.transform.position;
    _sortOrders[count] = TargetSpriteRenderer.sortingOrder;

    //Increase frame counter
    count++;
    //If we waited enough; open the ghost image.
    if (count == DelayInFrames) {
      count = 0;
      if (!delayCompleted) {
        delayCompleted = true;
        GhostSpriteRenderer.enabled = true;
      }
    }
    //Now counter is referencing to oldest positions/orders we have; so use them:
    if (delayCompleted) {
      GhostSpriteRenderer.transform.position = _positions[count];
      GhostSpriteRenderer.sortingOrder = _sortOrders[count];
    }
  }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .