Q:

How can I create an aperture-closing effect?

I'm looking to create an effect like this in a game I'm making:

I would describe it as a camera aperture closing.
I have the following requirements:

I need to be able to reverse the fade (open the aperture instead of close it)
The hole should close/open towards/from a given center point.

I can't really think of a great way to do this. I'm so used to SpriteBatch and Texture2D that I don't know how I could draw an ellipse style effect.
My current thoughts would be to make a few Texture2D frames and then animated them on the screen but that seems crazy.
If I just wanted to create pseudo-code to do it, it would probably look something like this (coming from a GDI/GDI+ background):
Call: Create_Relevant_Ellipse_Bounds;
Call: Set_Graphics_Exclusion_Clip_From_Ellipse;
Call: Fill_BackColor_With_Black_Using_Clip;
Call: Update_Ellipse_Bounds;
Call: Wait_For_Next_Draw;

A:

A point p is inside a circle at c with radius r when
(p.x - c.x)^2 + (p.y - c.y)^2 < r^2

is true. Using this equation you can color any points inside a circle one color (such as "transparent") and anything outside the circle a different color (such as "black"). You can even fade the edges of the circle, if you are so inclined.
You can write a custom shader to do this, and apply it to a full-screen quad. Set up shader constants defining the center of the circle and the current radius, and draw your quad. Every frame, decrease the radius by some factor to animate the circle getting smaller.
SV_Position contains the fragment position in D3D10 and up, but it's not available in D3D9 (which is what XNA is based on). Instead you can use the VPOS semantic (more information here). This will give you the position of p for the above equation. c and r come from your shader constants.
You can use the step function to return 0 or 1 based on which side of the equation is greater. This will allow you to avoid an actual branch in the shader, so you can compute the alpha component of your final color like this:
// alpha will be 1 if (r * r) is greater, meaning c is outside the radius.
// Ptherwise it will be zero.
float alpha = step(pow(p.x - c.x, 2) + pow(p.y - c.y, 2), r * r)

return (0,0,0,alpha);

If you didn't have SV_Position or VPOS available, you could always just put texture coordinates in the quad vertices. These will be interpolated across the face of the quad during rasterization, and can be used as an approximate coordinate system for specifying the position and radius of the camera aperture.

