0
\$\begingroup\$

I'm working on creating an iris wipe transition, like the ones you see in old cartoons - a fully transparent circle closes on a certain point, leaving a full screen of a solid color. Additionally, the background around the circle fades in from full transparency as well. I decided that shaders would be easier than creating vertices to build the iris effect. I may have been wrong.

EDIT: I've made some progress since asking this question - there is now an iris effect, but it opens and closes around a blank CornflowerBlue screen before displaying the screen, and the background around the circle is always full transparency.

Shader:

sampler TextureSampler : register(s0);
float2 irisCenter;
float radius;
float4 backColor;

float4 PixelShaderFunction(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 coords: TEXCOORD0) : COLOR0
{
    float4 p = pos;
    float2 c = irisCenter;
    float r = radius;

    float alpha = abs(1 - step(pow(p.x - c.x, 2) + pow(p.y - c.y, 2), r * r));
    return float4(backColor.r, backColor.g, backColor.b, alpha * backColor.a);
}

technique Technique1
{
    pass Pass1
    {
        PixelShader = compile ps_3_0 PixelShaderFunction();
    }
}

The alpha variable should be deciding if a pixel is inside the circle and should be transparent, or if the pixel is outside the circle and shouldn't be. irisCenter, radius, and backColor are all set on each frame by:

public void Draw()
{
    if (isInitialized && (isRunning || dir == EffectDirection.Backward))
    {
        float r = color.R; // / 255f;
        float g = color.G; // / 255f;
        float b = color.B; // / 255f;
        float a = (color.A * currentFadeLevel); // / 255f;

        var irisEffect = GameServices.Effects["IrisEffect"];
        irisEffect.Parameters["irisCenter"].SetValue(irisCenter);
        irisEffect.Parameters["radius"].SetValue(irisRadius);
        irisEffect.Parameters["backColor"].SetValue(new Vector4(r, g, b, a));

        quadRenderer.Render(irisEffect);
    }
}

IrisEffect.cs

QuadRenderer.cs

Instead of behaving as an iris wipe, it first draws a full-screen rectangle for half the effect, and then a full-screen Color.CornflowerBlue rectangle (I guess the quad from QuadRenderer isn't drawing with transparency). I'm not sure what's wrong as I'm new to HLSL.

Question 1: How can I get the coordinates of the current pixel being processed by the shader?

Question 2: What am I doing wrong?

Question 3: How do I draw the rest of the quad transparently?

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

Well, turns out I had my draw calls in the wrong order. Drawing the effect last, after everything else in the scene, solves all my issues. Also, the complicated vertice trickery in QuadRenderer can be replaced with a simple call to a helper method I have that draws rectangles of arbitrary colors.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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