This project is read-only.

CreateConvex ShadowHull issue

Jan 25, 2011 at 10:04 AM
Edited Jan 26, 2011 at 12:03 PM

EDIT: think I've identified the issue, here...? See my 4th post for details :)

Hi! I'm using Farseer Physics for the structure of my game, and I've just implemented Krypton (which was a breeze, and looks instantly gorgous... great project :))

I'm having some issues getting the two to behave - the 'tiles' in the image below are created from a Texture2D, Farseer uses an Earclip Decompressor to work out a poly and convert it to Farseer fixtures. Works really well, and I was hoping it'd be relatively simple to grab the list of Vertices it produces during that process and use them to create a ShadowHull for each tile.

It's sort of working, but I'm getting some weird behaviour, as seen in the image.

http://img8.imageshack.us/img8/8198/krypton.png

 

My light source is hidden by certain parts of the poly, and not others.

You'll also notice that no debug ShadowHull is being drawn, even though the light's reacting to one. Doing some simple tests, I think that's because Debug only draws ShadowHulls when the vertices it gets fed are clockwise. I'm not sure, but I think the verts I'm getting from the Farseer Earclip aren't. I don't think they're counter-clockwise either, because otherwise a simple reverse() of the list should draw a ShadowHull, right?

So I'm left thinking that my Verts are ordered left-to-right, or something. I'm not sure.

Any advice? Here's some code for what's happening:

 

public List<Vertices> getVertsFromTexture(String sTexture, Vector2 vSize)
        {
            //load texture that represents the body
            Texture2D polygonTexture = getTextureFromSpriteSheet(spriteSheet, sTexture);

            //Create an array to hold the data from the texture
            uint[] data = new uint[polygonTexture.Width * polygonTexture.Height];

            //Transfer the texture data to the array
            polygonTexture.GetData(data);

            //Find the vertices that makes up the outline of the shape in the texture
            Vertices verts = PolygonTools.CreatePolygon(data, polygonTexture.Width, polygonTexture.Height, false);
            
            //Since it is a concave polygon, we need to partition it into several smaller convex polygons
            List<Vertices> _list =  EarclipDecomposer.ConvexPartition(verts); 
   
            return _list;
        
        }

 

 

I'm then creating my ShadowHulls based on that _list:

 

            for (int i = 0; i < _list.Count; i++)
            {
                Vector2[] polygon = _list[i].ToArray();

                if (polygon != null && polygon.Length >= 3)
                {
                    var _hull = ShadowHull.CreateConvex(ref polygon);
                    _hull.Position = vPosition;
                    _hull.Angle = fAngle;
                     krypton.Hulls.Add(_hull);
                }
            }         

 

I'm hoping I'm just doing something really stupid here... any idea what that might be?

Jan 25, 2011 at 10:22 AM

The problem I see is that the shadows are drawn over the hulls. The solution to this (at least as I will try to solve it, once I solve my camera problems - Similar to PhoenixWright's) would be to draw the hulls (with solid textures) after the shadows have been drawn, so they are above it.

Jan 25, 2011 at 10:32 AM
Edited Jan 25, 2011 at 11:12 AM

Yep, I can draw the tiles' texture on top to cover the mess, but it's not an ideal solution.  The ShadowHull should be directly on top of the Farseer fixtures, same shape, no?

Edit: my point being that any texture calls after krypton.Draw won't be affected by the AmbientColor light level settings, etc.

 

I'm looking at this mysterious Camera issue now, will post if I come up with anything. Weird that mine works and yours don't, my code's pretty similar ;)

Jan 25, 2011 at 1:37 PM

Uhm,, you are right about the problem that the tiles will not be affected by the ambient color.

Yep, the camera stuff is quite strange. I'm working on changing my camera class to see if something is wrong there.

Jan 25, 2011 at 5:33 PM

Small update; I've changed the code slightly so I'm casting back each of Farseer's convex Fixtures to a Poly, and getting the vertices from there. When I reverse the order of the array, the ShadowHulls are drawn in Debug mode, but I'm getting the same issue as the screenshot above.

 

PolygonShape poly = (PolygonShape)fixture.Shape;

Vector2[] v = poly.Vertices.ToArray();
Array.Reverse(v);

   var _hull = ShadowHull.CreateConvex(ref v);
   _hull.Position = vPosition;
   _hull.Angle = fAngle;

krypton.Hulls.Add(_hull);

 

So I'm back to Square One as to what the actual issue here is; I'm creating ShadowHulls that are an exact replica of my poly, but it seems as though one edge of the Hull allows light through (as per image).

??

Jan 25, 2011 at 5:46 PM
Edited Jan 25, 2011 at 6:10 PM

Ok... so now that I've got ShadowHulls showing up in debug mode, I ran a little test.

Two square hulls, side by side. Generated with the following code. 

 

		Vector2[] polygon = new Vector2[]
                {
                 // hull only drawn if poly is ANTICLOCKWISE
                 new Vector2(3,0),
                 new Vector2(0,0),
                 new Vector2(0,3),
                 new Vector2(3,3),
                };


                 var _hull = ShadowHull.CreateConvex(ref polygon);
                 _hull.Position = vPosition;
                 _hull.Angle = fAngle;
                     
                krypton.Hulls.Add(_hull);



                Vector2[] polygon2 = new Vector2[]
                {
                 // hull only drawn if poly is ANTICLOCKWISE
                 new Vector2(6,0),
                 new Vector2(3,0),
                 new Vector2(3,3),
                 new Vector2(6,3),
                };


                  _hull = ShadowHull.CreateConvex(ref polygon2);
                  _hull.Position = vPosition;
                  _hull.Angle = fAngle;
                     
                krypton.Hulls.Add(_hull);

 

http://img217.imageshack.us/img217/1290/kry.png

See how the light is blocked by the left-most Hull, but is seeping through the right one? And then is blocked by the second hull...

That's the same issue Ithink I've got with my tiles -when they're broken down to convex polys they're side by side and the light is blocked by the first, but bleeds into the second.

Is this a bug? Or am I missing a setting somewhere?

 

EDIT: testing further with CreateRectangle instead of CreateConvex, it looks like this isn't a bug, but expected behaviour. But it does look odd, especially where polys are concerned... can anything be done about it?

Jan 25, 2011 at 8:02 PM

Hey, zombiecow.

Actually, I didn't consider this a "bug", but simply the default behaviour of the effect. There's a few different shader technique's in the effect file for the point light.

The current technique is PointLight_ShadowWithOcclusion, and will allow shadow hulls to draw shadows on other shadow hulls (the issue you see above.)

I would suggest using eith of the following:

  • PointLight_ShadowWithIllumination - Draws shadows from shadow hulls, but does not draw shadows on any shadow hulls.
  • PointLight_Shadow - Draws shadows from shadow hulls, and on top of shadow hulls. the hull which casts the shadow will also be in shadow.

You can change this in the PointLight.cs file. I'll probably add some functionality to make this simpler, though, and allow for a more "global" effect. IE, create a single place to store default techniques.

Hope this helps, and is what you're looking for :)

 

 

 

Jan 25, 2011 at 8:16 PM

Oh God it works a charm. I owe you a pint :)

Are there any more shader effects to try out?

 

Jan 25, 2011 at 10:01 PM

I'm not sure I've added many other implicit features... There could be a blur technique in there, but that requires some setup.

Jan 26, 2011 at 6:05 AM

Whoops. the PointLight_ShadowWithIllumination technique didn't quite work out how I had intended it. I've changed that now and it's checked it.

Jan 26, 2011 at 11:07 AM

Hi xixonia, I have a related question about the techniques. In terms of performance I guess that PointLight_Shadow performs (maybe slighlty) better than PointLight_ShadowWithIllumination, right? Or they have no difference?

Jan 26, 2011 at 7:35 PM

Pnikosis,

Correct. PointLight_Shadow uses only one pass, whereas the other shadow techniques use two passes to render shadows, thus making the PointLight_Shadow technique faster.

Jan 27, 2011 at 9:27 AM

I'll probably add some functionality to make this simpler, though, and allow for a more "global" effect. IE, create a single place to store default techniques.


Just as a thought - is it possible/ worth it to add this as a hull-side parameter? So certain Hulls can have NoShadow, some with Illumination etc?

Jan 27, 2011 at 2:16 PM

Haha, I had the same thought last night.

I'm thinking of different ways of doing this...

Obviously we can set the technique per hull, and render per hull, but this would be very slow for different hulls. It may be fast enough to mimic spriteBatch's sorting functionality, so we can "draw immediate, or "sort by shadow type"...

Do you have a use for this at the moment, or are you just making a suggestion :) ?

Jan 27, 2011 at 5:00 PM

Just making a suggestion, really. Now I've got Krypton plugged in and integrated and running nicely, I'm thinking through what it is/ isn't possible to do. I'm aware this is something I'd probably find very useful at some point :)

 

Jan 27, 2011 at 5:12 PM

I agree! If you have anything specific in mind, let me know, as I'm trying to balance performance with functionality. Sometimes you have to give up one to get the other.

Jan 28, 2011 at 8:14 AM

Further to this, I was thinking about Hull settings. It's be pretty helpful to have a Hull parameter that dictates what percentage of light it blocks - so if it's 100, nothing gets through.

Below that, the light alpha of the 'blocked' area would increase, so although there's shadow being cast it's not complete occlusion.

At 0 light goes straight through the hull. Just a thought. ;)

Jan 28, 2011 at 8:29 AM

I seem to remember toying around with this previously, and ran into a few issues... I don't think it should be a problem now, as that was well over a year ago, and I've learned a lot since then.

If you have any specific feature requests, it would be awesome if you could open a new work item for it. The opacity parameter is a perfect example of what I'd like to see in the issue tracker.

Jan 28, 2011 at 9:22 AM

Will do :)