BoltBait's Pages - Reflections

Sarcasm, just one of the services I offer.

 

Paint.NET Reflection Filter

The other day, I needed to create some graphics with reflections (sometimes called "Wet Floor").  Lots of sites that want to have a "Web 2.0" look use this type of graphic.  Here is an example:

Wow, what a pain that turned out to be.  There was no easy way to do this using Paint.NET.  So, of course, I decided to write an "Effect" that would do it.

The Effect DLL

You can download the precompiled effect DLL here: ReflectionFlat.dll

Just drop this file in your \program files\Paint.NET\effects directory and you should be all set.

Instructions for Use

1) Start with a new graphic and create a new layer that is totally transparent.

2) On that layer, place the object that you want to make a reflection for.

3) Select the area where you want the reflection to show and run the effect:

You'll need to tinker with the depth and MaxAlpha variables to get something workable.

Also, you may need to ignore some pixels of the object.  Here is an example:

Notice how the bottom of the yellow box is showing in the reflection.  Just increase the Ignore value to get rid of that.  Here it is shown with an Ignore value of 3:

You can then "Merge Down" Layer 2 to complete your graphic.

Source Code

Here is the source code to the main render function (which you can use right in CodeLab):

void Render(Surface dst, Surface src, Rectangle rect) 
{ 
    int depth = 100;    // maximum distance of the reflection 
    int MaxAlpha = 128; // darkest reflection (255-0, default 128) 
    int ignore = 0;     // bottom pixels of object to ignore 

    PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds); 
    Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); 
    ColorBgra CurrentPixel; 
    for(int y = rect.Top; y < rect.Bottom; y++) 
    { 
        for (int x = rect.Left; x < rect.Right; x++) 
        { 
            if (selectionRegion.IsVisible(x, y)) 
            { 
                CurrentPixel = src[x,y]; // Get the current pixel 
                if (CurrentPixel.A == 0) // is it transparent? 
                { 
                    int y1=0; 
                    int yd=0; 
                    for (y1=y; y1 > 0; y1--) 
                    { 
                        if ((y1 != selection.Top) && (src[x,y1].A == 0)) 
                        { 
                            yd++; 
                        } 
                        else 
                        { 
                            break; 
                        } 
                    } 
                    if (y1+1-yd-ignore >= 0) 
                    { 
                        CurrentPixel=src[x,y1+1-yd-ignore]; 
                        if (CurrentPixel.A > 0) 
                           if (yd

OK, I hope you have found this effect useful.

Monday, November 6, 2006