libgdx / box2dlights

Fork of box2dlights by Kalle Hamalainen
Apache License 2.0
255 stars 82 forks source link

Allow to set the length of shadows #40

Open haimat opened 9 years ago

haimat commented 9 years ago

Currently in box2dlights a box2d body either casts a shadow or not, there is no in-between. However, in my application I need to specify the length of the shadow for each object, depending on the objects height (in order to simulate a 3d effect).

For example, if the object that would cast the shadow is tall then the shadow is long. But if the object is small, not as tall as the light source height, then the shadow would be shorter.

Would it be hard to implement such a feature in box2dlights?

rinold commented 9 years ago

Hi there, thank you for your idea/question.

It's looks like an interesting feature but currently I don't see how it could be implemented, the reason is - for such tall dependent shadow effect the light should be able to acquire from each fixture it's "tall" and currently I don't see where it could be stored, except the user data, which often is used for the different purposes.

Still before any final answer I'll need to check if the ray-casting could handle such cases at all, cause I'm not 100% sure regarding the current implementation.

haimat commented 9 years ago

Ohh yes, that indeed sounds like an issue. But is there no attribute within box2d fixtures or bodies (beside the user data), which we could use to store that "height" additional value?

haimat commented 9 years ago

I was thinking about that. How about optionally using the user data to store the "tall" value of the object, if you want shadows with different length. In that case you can't use the user data for something else, but since it's optionally you can choose not to use it as well...

rinold commented 9 years ago

I also was thinking about that, however it will be a rare case, in most of engines the userData is often used to connect physics body with other engine elements (like graphical objects). But I will try to see what we can do.

haimat commented 9 years ago

Thank you very much for your efforts!

rinold commented 9 years ago

Hi @haimat,

I have a question - as I understand the "tall" is not enough, we will need a lights "height" position also? Or in your idea of implementation all lights are on the same height?

Also, it's quite hard for me, as I'm not expert, but seems I was able to find some way to do it: image

This is draft implementation of shadows for Directional lights. Will try other light too, but it will be even harder :) Need to find a way to handle ray collision overlapping, e.g. if the light is blocked by fixture, but the fixture next to it is far enough to drop the shadow from this light also... it's a pain my head :) sorry for my english, btw.

haimat commented 9 years ago

Wow, that looks already awesome -- great work! Now if you could manage to get that working for point lights too, I would be super happy :-)

To your question: Of course you are right, to be more realistic we would need not only the height of the fixture ("tall"), but also the height of the light source. This would be nice, but having only one value to control the length of the shadow would be better then what we have now.

So in other words: having both, "object height" (tall) and "light height" would be great, but having only "object height" (one valiue) would also be fine!

rinold commented 9 years ago

Hi @haimat,

Just interesting, is it possible for you to link not the pre-build jar library but add the box2dlight source project as dependency?

haimat commented 9 years ago

You mean for testing your changes? Sure, no problem, I can do that!

rinold commented 9 years ago

That would be great! You can use my fork, its could be found by referenced commit above. Current implementation looks good on screenshots, but isn't optimised and I feel its buggy. To use limited height lights you need do 3 things:

  1. Enable experimental mode using rayHandler.setPseudo3dLight(true)
  2. Set fixtures user data to new LightData(height) objects
  3. Set PointLight.setHeight(lightHeight)

And currently it works only for PolygonShape fixtures, tell me what other Shape types you are using to prioritise the implementation for real testing :-)

haimat commented 9 years ago

So, I did what you suggested, using your fork and enabling the new pseudo-3d feature. It does work partially: when the fixture is within the point light range, then it seems to work fine. However, when I move the light away from the fixture, then the shadow becomes bright, like light. Hard to explain, so have a look at these screenshots.

This is correct: Good Shadow

And this is wrong: Bad Shadow

rinold commented 9 years ago

Oh... could you please share your sample box2dlights setup configuration in your project and sample height values for this issue?

haimat commented 9 years ago
fixture.setUserData(new LightData(1.0));

pointLight.setHeight(2.0);
pointLight.setColor(Color.WHITE);
pointLight.setDistance(10.0);  // in my world-dimensions, 1 unit = 64 pixels

RayHandler.setGammaCorrection(false);
rayHandler.useDiffuseLight(true);
rayHandler.setBlurNum(3);
rayHandler.setAmbientLight(0.2, 0.2, 0.2, 1.0);
rinold commented 9 years ago

Seems I've messed up some blending and we had different ambient light set. On my (0f, 0f, 0f, 0.5f) this wasn't visible - both blendings gave the same good result. I've pushed the possible fix, give it a try when you have chance! And also, thanks for your time :)

haimat commented 9 years ago

Thanks for your last update, it looks already pretty great! There is a bug however -- again, hard to explain. The shadows cast by the polygons now look as if you would look down into an empty cylinder, i.e. as if the polygon was hollow. Additionally, for every polygon I tried in different shapes and with different numbers of vertices the shadow looks as if one side of the polygon would be missing.

With a bit distance the shadow looks good: Good Shadow

Moving the light closer makes the polygon appear hollow: Hollow Polygon

One border/side seems to be missing (not casting any shadow): Side Missing 1

And again: Side Missing 2

But it looks really good already. Seems you are quite close :-)

rinold commented 9 years ago

I've tried to do more testing this time :) you can sync with new version and look at it again.

rinold commented 9 years ago

Ohh... I've added the userData field to LightData - it solves one general limitation:

    // If it was in your project:
    fixture.setUserData(customData);
    ...
    // Still could be used with modification as:
    fixture.setUserData(new LightData(customData, lightHeight));
    ...
    // And get it back with:
    YourDataType data = (YourDataType) LightData.getUserData(fixture);

So you still could use custom data even with pseudo-3d mode enabled, just adds a bit more pain in getting it later :) Don't know why I haven't thought about it earlier.

haimat commented 9 years ago

Hmm, I'm afraid it stills seems a bit buggy. Sometimes (when the light source is in a certain angle to the polygon) a polygon side closer to the light source casts a shadow onto the polygon, that doesn't look right.

Wrong Shadow

rinold commented 9 years ago

I've updated code, should fix this issue. Btw, non-convex polygons still are not supported correctly, but should work fine with convex shapes.

haimat commented 9 years ago

Thank you very much. It's already looking awesome! There are two things I noticed though:

  1. When the light source is inside the polygon, then the closest side of it does not cast any shadow
  2. It seems to make no difference whether the light source height > polygon fixture height

For the 2nd point I also think the the inside of the poygon should be in shadow if the polygon fixture height is > then the light source height. What do you think about that?

rinold commented 9 years ago

I will check the inside case later. For now I've fixed some shadow length computation, and it will be great if you will try following mode:

rayHandler.setPseudo3dLight(true, true);

The second param if true - enables some shadow color interpolation, which looks a bit different - but I don't know which is better :)

Regarding to shadowing the polygon in case of light height < then fixture height sounds reasonably. I will check it also.

haimat commented 9 years ago

I have tried the new parameter to interpolate the shadows. It indeed looks smoother = nicer now :-)

rinold commented 9 years ago

Hi @haimat,

I've found that current implementation is a bit awful :) it doesn't work for colored lights as usual box2dlight do. I need to re-implement the core, and also due to memory and performance optimization I'm going to move all the code related to this feature to a separate sub-package.

The following development will continue on the libgdx "pseudo3d" branch and I will talk with libgdx team if its possible to move box2dlights nightlies build to this branch also so that you could easily update and test it during development via Gradle and smoothly move onto it when it will be merged to master branch. Also after the first commit to the "pseudo3d" branch it will be better to create issues/enhancements in a separate threads.

P.S. This will take some time, but hope soon you will be able to use it again and it will be event better :) Thanks for your idea and time!

haimat commented 9 years ago

Thank you very much for your feedback. So will you answer here in this thread when you have a new version ready for testing, or somewhere else?

rinold commented 9 years ago

Yes, I will notify you in this thread :)

jayaxel commented 9 years ago

Hi, have there been further updates regarding the pseudo 3d lights?

rinold commented 9 years ago

I'm quite a busy currently on my job, having a few free time. Even now at holiday I'm writing this from work :) you can check it's current status at box2dlights "pseudo3d" branch, unfortunately there is no built jar could be provided currently, but you can still try it from sources.

fiz192 commented 9 years ago

This should be in Libgdx official release good job guys!

danikaze commented 9 years ago

Any plan of a pull request to join it to the master branch? :D

rinold commented 9 years ago

It might be, but currently the pseudo3d branch is "28 commits behind master" which sounds a bit frightening for the merge :) This will take much work...

danikaze commented 9 years ago

Oohh... this can be sooo great if integrated in the master branch >_<

mattbl commented 8 years ago

That looks so promising and interesting feature. Any hope to see it merged with master someday?

kabilzamandar commented 8 years ago

Hi, i'm quite new to github and box 2d lights. How can i implement your code with existing box 2d light library? I took the code from https://github.com/rinold/box2dlights, but i didn't see pointlight.setHeight or pseudo3d. Any help is appreciated.

mattbl commented 8 years ago

It's on the 'pseudo3d' branch at the moment.

kabilzamandar commented 8 years ago

Thanks. I have few questions related box 2d directional light and shadowing. I'm using a conelight and a directional light with changing alpha to simulate day and night cycles. When i set conelight active, i'm facing flickering light borders. It does'not look so good. Do you have any idea how can it be solved?

Another issue is, i setrayHandler.setPseudo3dLight(true, true); and rays pass through the bodies, why does it happen?

rinold commented 8 years ago

You can try to increase the rays number for the lights - it's usually the second argument in co structor (called 'rays') to reduce flickering.

Regarding to the pseudo3d lights you should use the box2dlights.p3d.P3dLightManager (pseudo3d ray handler analogue) to handle the P3d lights.

Sorry for any inconveniences, but I'm currently writing from phone, having no access to my laptop (hope will get back in a week), thus unfortunatelly can't show code examples now.

danikaze commented 8 years ago

I'm afraid to ask but... I guess this pseudo3d branch is dead? given the number of updates lately...

BambooBandit commented 7 years ago

Hopeful for this addition to the main branch. This'll really add icing to the cake

nicky24 commented 7 years ago

How can I integrate this branch with my Android Studio with LibGDX project?

rinold commented 7 years ago

Unfortunately, for now the only way is to download it's sources and build jar on your own, or add downloaded project as dependency.

kdenzel commented 4 years ago

Hi @rinold, i needed this pseudo3d from a top down persective and i felt so free to take your code, edit it and merge it with the current box2d-lights Version. Good work. I only used the directional light. You can visit the code on my github repo. Maybe it is to specific for my needs but it works in my case. Maybe we can merge this feature into the 1.6 version? If you run the tests (maybe you have to change the resource paths in the Test class) you can see a full sun cyclus when activated the directional light.