Sign in to follow this  
BoltBait

Object Reflections Plugin - Wet Floor Effect

Recommended Posts

Compiled DLL (Thanks to MadJik): <!-- m -->http://jcljay.free.fr/pdn/ReflectionFlat.zip<!-- m -->

I need to make some graphics with reflections similar to the following:

ReflectResults.jpg

What a pain! Well, really only the one on the right turned out to be a pain.

Anyway, I tinkered around in code lab and wrote the following codelab script: (This is the updated script)

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<depth)
                           {
                               // fade the reflection out
                               CurrentPixel.A = (byte)(((double)MaxAlpha/depth)*(depth-yd)*CurrentPixel.A/255);
                           }
                           else
                           {
                               CurrentPixel.A = 0; // totally faded at this point
                           }
                    }
                }
                dst[x,y] = CurrentPixel;
            }
        }
    }
} 

Instructions for use:

1) 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.

4) Run the codelab script:

Reflect1.jpg

Sometimes you will want to ignore the bottom of the object like in this example:

Reflect2.jpg

5) 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:

Reflect3.jpg

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

Thanks, MadJik for putting a UI on this one!

Share this post


Link to post
Share on other sites

Hmm. Looks like you're mangling alpha values.

CurrentPixel.A = (byte)((MaxAlpha/depth)*(depth-yd));

It's not taking into account the value of CurrentPixel.A. Perhaps if you multiply the right side of the assignment expression by CurrentPixel.A, then divide by 255, then cast to byte, it will be correct.

Share this post


Link to post
Share on other sites
Hmm. Looks like you're mangling alpha values.

Yeah, thanks. I hadn't even thought about that. I only spent about 1/2 hour on this so I knew it would have problems.

The refection is kinda not anti-aliased... maybe because of the alpha values?

Yeah, that's what Rick said. ;)

Hey! I told you it was rough. :D

Just looking at it, I see there is another bug in there too:

if ((y1 == rect.Top) || (src[x,y1].A == 0))

should be:

if ((y1 != selection.Top) && (src[x,y1].A == 0))

I keep forgetting to use selection instead of rect. :D

And then, of course, I need to add the following at the top of the function:

Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); 

That will cause the reflection to start at the top of the selection if the selection does not have any non-transparent pixels in it. This eliminates the need to draw a line under text and other odd shapes that I said before. That was my original intent, but I couldn't figure out why it wasn't working. :D

OK, so here's the updated code. The effect is starting to look pretty good...

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) 

   PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds); 
   Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); 
   ColorBgra CurrentPixel; 
   for(int y = rect.Top; y     { 
       for (int x = rect.Left; 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 >= 0) 
                   { 
                       CurrentPixel=src[x,y1+1-yd];  // look in the mirror 
                       if (CurrentPixel.A > 0) 
                          if (yd                           { 
                              // fade the reflection out 
                              CurrentPixel.A = (byte)((MaxAlpha/depth)*(depth-yd)*CurrentPixel.A/255); 
                          } 
                          else 
                          { 
                              // totally faded at this point 
                              CurrentPixel.A = 0; 
                          } 
                   } 
               } 
               dst[x,y] = CurrentPixel; 
           } 
       } 
   } 
}

DO NOT USE THIS SCRIPT, IT HAS BEEN UPDATED BELOW.

Well, I think one thing left to do is to be able to specify an amount of pixels to ignore before starting the reflection. I'll add that capability on Monday. Then I'll ask Illnab1024 to put a UI on it--that is, if you all think its worth it. Let me know.

Share this post


Link to post
Share on other sites
Well, I think one thing left to do is to be able to specify an amount of pixels to ignore before starting the reflection. I'll add that capability on Monday. Then I'll ask Illnab1024 to put a UI on it--that is, if you all think its worth it. Let me know.

OK, that was easy...

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     { 
       for (int x = rect.Left; 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                           { 
                              // fade the reflection out 
                              CurrentPixel.A = (byte)((MaxAlpha/depth)*(depth-yd)*CurrentPixel.A/255); 
                          } 
                          else 
                          { 
                              CurrentPixel.A = 0; // totally faded at this point
                          } 
                   } 
               } 
               dst[x,y] = CurrentPixel; 
           } 
       } 
   } 
}

DON'T USE THIS AS THERE IS A BUG IN IT. USE THE ONE IN MY ORIGINAL POST.

Well, I'm done playing with this.

OK, screenshots have been updated (not on this thread though, sorry). Go here for the whole story:

http://boltbait.googlepages.com/reflections

Enjoy. 8)

Share this post


Link to post
Share on other sites
:wink: :D Yeahh ! Very interesting effect ! When will we be able to download the DLL ? Thanks Boltbait . :wink:

Thanks!

Illnab1024 ran into a little trouble with the UI. He's still working on it. Stay tuned...

8)

Share this post


Link to post
Share on other sites
My eyes hurt...

Maybe you should take some asprin. :roll:

I have a question, is there a reason it sizes the original image up?

I'm not sure what you mean. Could you show a screenshot?

Share this post


Link to post
Share on other sites
Look at your example, the lines get thicker in the reflection.

No, actually, they don't.

Share this post


Link to post
Share on other sites
It was updated...BAH!

Trust me, the original did.

That actually may be possible. The original script I wrote was not treating alpha values properly.

After Rick pointed that out, I updated the script and published the results on my googlepages. However, I never went back here and updated the screenshots.

Well, today I updated the screenshots on this thread.

Share this post


Link to post
Share on other sites

thats what I was talking about , the original screenshot, with the line under boltbait had the reflection enlarged...I was wondering if it was a setting.

Share this post


Link to post
Share on other sites
:shock: Hey! How did you make the "" effect waves "" ? :shock:

I used the codelab Warp.cs (provided with codelab plugin).

void Render(Surface dst, Surface src, Rectangle rect)
{ 
   float Radius = 2.0f; // Wave Radius
   float XCoef = 0.8f;  // X divider
   float YCoef = 0.3f;  // Y divider

       for(int y = rect.Top; y < rect.Bottom; y++)
   {
       for (int x = rect.Left; x < rect.Right; x++)
       {
           dst[x, y] = src.GetBilinearSample(
x+ Radius  * (float)(
                   Math.Sin((x + y / YCoef ) / (YCoef * 10))-
                   Math.Cos((y - x / XCoef) / (XCoef * 10))),
y- Radius  * (float)(
                   Math.Sin((x + y / YCoef ) / (YCoef * 10))+
                   Math.Cos((y - x / XCoef ) / (XCoef * 10))),
               true
               );
       }
   } 
}

I changed it in order to play with parameters...

float Radius = 2.0f; // Wave Radius

float XCoef = 0.8f; // X divider

float YCoef = 0.3f; // Y divider

Try it with different values.

Share this post


Link to post
Share on other sites
What do you think about having a DLL for that :

Here is it !

I took the Glow Effect source to build this once...

MadJik, could you grab the render function out of my original post on this thread and recompile? There was a bug in it that I fixed tonight.

To see the bug, simply set Depth > MaxAlpha. You will see the reflection disappear. This was due to integer math--I was missing a typecast to Double in the alpha calculation.

Share this post


Link to post
Share on other sites

MadJik, could you grab the render function out of my original post on this thread and recompile? There was a bug in it that I fixed tonight.

The zip file is updated...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this