7
\$\begingroup\$

For those who doesn't know:

An iris wipe is a wipe that takes the shape of a growing or shrinking circle. It has been frequently used in animated short subjects, such as those in the Looney Tunes and Merrie Melodies cartoon series, to signify the end of a story. When used in this manner, the iris wipe may be centered around a certain focal point and may be used as a device for a "parting shot" joke, a fourth wall-breaching wink by a character, or other purposes.

Example from flasheff.com

Iris wipe from flasheff

Your answer may or may not include a coding sample, a language agnostic explanation is considered enough.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Further explanation for those unfamiliar: Animated gif of an iris wipe - note the wipe can open the next scene, or close the current scene (imagine it played in reverse). \$\endgroup\$
    – Ricket
    Oct 4, 2012 at 2:39
  • 1
    \$\begingroup\$ I think you need to specify the implementation platform. What is usefully efficient will depend greatly on what graphics operations are available. \$\endgroup\$
    – Kevin Reid
    Oct 4, 2012 at 3:52

3 Answers 3

10
\$\begingroup\$

In a 2D iPhone game I played recently, iris wipe effect was simply done using full screen sprites with some transparency :

enter image description here

These pictures are simply draw over the screen once everything else have been draw (like hud, background, ...).

You can easily build theses pictures in photoshop, gimp, flash or whatever 2D program you have.


You can also do it "realtime", by using 2D primitives that are available in your framework (you dont specify any). Here is an example in opengl (un-tested) :

void drawIris(float inner_radius)
{
   const float outer_radius = 300.0f; //something big enough to cover whole screen

   glBegin(GL_TRIANGLE_STRIP);
   for (int i = 0; i < 360; i++)
   {
      float degInRad = i * DEG2RAD;
      glVertex2f(cos(degInRad) * inner_radius, sin(degInRad) * inner_radius);
      glVertex2f(cos(degInRad) * outer_radius, sin(degInRad) * outer_radius);
   }
   glEnd();
}

//to change the way iris animation is done,
//you can replace this function by something else like smoothstep() function
float lerp(float a, float b, float t)
{
   return a * (1.0f - t) + b * t;
}

//usage :
drawIris(lerp(0.0f, 50.0f, time));

Here is how it works :

enter image description here

We draw a open circle with an outer radius bigger than the screen. Everything outside the screen will automatically be clipped by opengl. Inner radius is aperture size of iris.

\$\endgroup\$
3
  • \$\begingroup\$ Just to clarify, drawing one circle on top of the other 'subtract' the intersection area in this case? \$\endgroup\$
    – user9471
    Oct 4, 2012 at 15:20
  • \$\begingroup\$ No, we draw only once. Think of a unfilled circle with a huge border around (like a ring). \$\endgroup\$
    – tigrou
    Oct 4, 2012 at 23:29
  • \$\begingroup\$ If I caught somebody on my team using the texture approach on iOS, I'd give them a stern talking-to. That sort of large transparency would absolutely murder the frame rate on many of the devices (particularly the iPhone4 and iPad1). But it's probably the best approach on desktop/console. \$\endgroup\$ Nov 5, 2012 at 2:05
8
\$\begingroup\$

If using OpenGL or Direct3D, you can write a post-processing shader to do the job rather easily.

You'll be rendering a full-screen quad on top of the already rendered scene. The shader takes in (as a uniform) current radius of the iris (so you'll "animate" that on the CPU).

In the fragment/pixel shader, you'll get the current't pixel's screen coordinates from the interpolated vertex coordinates. You then calculate the distance to the center of the screen and output a black pixel if the distance is greater than the current iris radius, and a transparent one if not.

If you desire softer edges, you could look up vignette shader and animate its radius in the same way.

\$\endgroup\$
1
  • \$\begingroup\$ +1 for using pixel shaders (if available). That would make possibility of having smooth borders around iris easily. \$\endgroup\$
    – tigrou
    Oct 4, 2012 at 9:48
2
\$\begingroup\$

Another approach would be to generate a 2d mesh that has a hole in the middle, and render that on top of everything else.

Generating this mesh may seem complicated at first, especially when the hole is partially bigger than the screen, but remember that the mesh may be way bigger than the screen.

I'd go with something like a huge "o" circle shape.

Alternatively, you can use stencil buffers to first render the parts that you want to keep visible to the stencil buffer and then render a huge quad over everything using said stencil buffer.

\$\endgroup\$

You must log in to answer this question.